home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / database / eb108.zip / PACK1.PRG / EBOUT / EB2.REP < prev    next >
Text File  |  1996-11-10  |  177KB  |  4,913 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.                           EASY BASE USERS MANUAL
  7.                           ══════════════════════
  8.  
  9.                                 Contents
  10.                                 ────────
  11.  
  12.  
  13.  
  14.  
  15.             System Overview..............................   1
  16.  
  17.             Data Management Principles...................   2
  18.  
  19.             Form Design..................................   6
  20.  
  21.             Relationships and Lookups....................  11
  22.  
  23.             Data Entry...................................  15
  24.  
  25.             Procedures (Reporting).......................  20
  26.  
  27.             Procedures (Transactional)...................  36
  28.  
  29.             User Menus...................................  39
  30.  
  31.             External File Access.........................  43
  32.  
  33.             Data File Format.............................  45
  34.  
  35.             System Requirements and Limitations..........  46
  36.  
  37.             DOS Filename Convention......................  47
  38.  
  39.             Selected Programming Topics..................  49
  40.  
  41.  
  42.       Easy Base is copyright (c) John Turnbull 1994 published by:-
  43.  
  44.       Easy Software                  Tel/FAX (044) (0) 1625 614669
  45.       3 Brookside Court              CIS 100410,717
  46.       Prestbury Road
  47.       Macclesfield
  48.       SK10 3BR
  49.       UK
  50. ................................................................................
  51.  
  52.  
  53.  
  54.  
  55.                                TERMINOLOGY
  56.                                ═══════════
  57.  
  58.  
  59.      Field          The storage space for an individual data item.
  60.      ─────
  61.  
  62.      Record         A set of related data items.
  63.      ──────
  64.  
  65.      Form           The storage space for a set of records.
  66.      ────
  67.  
  68.      Procedure      A set of instructions which manipulate the data
  69.      ─────────      stored in forms.
  70.  
  71.      Relationship   A record in the relationships form recording
  72.      ────────────   a link between forms.
  73.  
  74. ................................................................................
  75.  
  76.  
  77.                       EASY BASE SYSTEM OVERVIEW
  78.  
  79.      Easy Base is a complete rapid programming system for data
  80.      management. Virtually every data management problem can be
  81.      broken down into three areas. Creating disk files (referred to
  82.      as "Forms" in Easy Base) in which to store data, creating
  83.      procedures which manipulate that data and presenting those
  84.      forms and procedures in a logical menu system for use.
  85.  
  86.      In Easy Base you create the forms in which to store data in a
  87.      simple screen-painting environment which not only designs the
  88.      data file but at the same time provides a default data entry
  89.      screen for your data. As you place the "Fields" in which data
  90.      is to be stored you can use relational links ("Lookups") to
  91.      import data from other forms. Each field you create for data
  92.      storage is also treated as a deriveable "Cell" similar to a
  93.      spread sheet. You can make almost any calculation or derivation
  94.      within a field as, apart from all arithmetic, relational and
  95.      logical operators, Easy Base also provides a set of over fifty
  96.      functions covering everything from Modulo arithmetic to
  97.      spelling out dates. Once you have created your forms you can
  98.      use the default screen to enter and view your data using the
  99.      "Data Entry" system.
  100.  
  101.      Once you have data stored you will need to be able to
  102.      manipulate it and report on it. Easy Base provides a combined
  103.      transaction and reporting system ("Procedure Generator"). With
  104.      the procedure generator you can use the default screens you
  105.      have designed or create custom screens in which to gather input
  106.      either from the keyboard or from relational Lookups. You then
  107.      instruct Easy Base what to do with this information using a
  108.      simple "Basic" like programming language. If your procedure is
  109.      transactional you have commands to enter, modify or delete
  110.      records in any number of forms within a single procedure. If
  111.      your procedure is reporting then there are commands to group,
  112.      order and list data in almost every conceivable way.
  113.  
  114.      You now have all the "Parts" required to create a useful data
  115.      management program. All that remains is to tie your procedures
  116.      to a menu system so that other people can use your application
  117.      without having to know anything about Easy Base. Creating an
  118.      end user menu system in Easy base is as simple as filling in a
  119.      form with the text you wish to display and the procedure or
  120.      form you wish to run. You give at least one of your menus a
  121.      start up password. If you then restart Easy Base but sign on
  122.      with that password instead of your developers password then you
  123.      will be running your own custom designed program.
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.                                  - 1 -
  132. ................................................................................
  133.  
  134.  
  135.                      DATA MANAGEMENT PRINCIPLES
  136.  
  137.      In Easy Base, creating forms and entering data is very easy.
  138.      You will be tempted to rush on and create programs for yourself
  139.      without reading the "Bumf". However, unless you are an
  140.      experienced data programmer, you should at least read this
  141.      section and the one on Relationships before embarking on any
  142.      serious project.
  143.  
  144.      The crux of data management is "Data Integrity" or "Data
  145.      Verification".  You might know that "A Smith", "Smith's Garage"
  146.      and "Smith and Son" are all the same customer of yours but your
  147.      computer definitely does not! If you have a small business you
  148.      might wish to use Easy Base to create invoices - you might be
  149.      tempted to start by creating an invoice form in which you enter
  150.      your customers name, work done and price. - DON'T - Start
  151.      instead by creating a form to hold each of your customers'
  152.      names, addresses, credit limit etc.  If you sell things then
  153.      create a form to hold each of your stock items with their name,
  154.      partno, price etc.  These are your "Core" data forms from
  155.      which you "Lookup" data for other purposes. Each of your "Core"
  156.      data forms has a "Unique" field which defines the record as an
  157.      entity. "Smith's Garage" will always be "Smith's Garage" and
  158.      the lookup function described later will not allow any other
  159.      representation to be entered.
  160.  
  161.      Although of less significance than "Data Integrity", the names
  162.      which you give to forms and fields are very important and worth
  163.      mentioning now. When you come to write "Lookup" derivations and
  164.      later, Procedural code you have to refer to your data by a
  165.      combination of its form and field names. Please give
  166.      considerable thought to the names you use. Each name should be
  167.      short but fully describe the form or field. The names of forms
  168.      should be plural and the names of fields singular. For example
  169.      - a form which is to hold details of your customers should be
  170.      called "Customers", the name field should be called "Name" and
  171.      the credit limit field should be called "Creditlimit" . When
  172.      you need to lookup data from this form the lookup function will
  173.      be written - Lookup(customers,name) and when you write
  174.      procedures the data will be referred to as customers.name ,
  175.      customers.creditlimit etc.  If you did not follow this naming
  176.      convention and called the form "F1" , the name field "customer"
  177.      and the credit limit field "Max cred" then writing procedure
  178.      code would be extremely frustrating.
  179.  
  180.      It is equally important to give the same name to fields which
  181.      hold the same data in different forms. If you already had a
  182.      form called "Employees" which had fields "Worksno", "Name",
  183.      "Address" and "Taxcode" and you then created a "Payslips" form
  184.      the fields which hold the employee's name and taxcode should
  185.      also be called "Name" and "Taxcode". This not only makes it
  186.      easier to remember field names but when you come to write
  187.  
  188.  
  189.                                  - 2 -
  190. ................................................................................
  191.  
  192.  
  193.      procedure code, data can be transferred between one form and
  194.      another with the command "Copy all from". This command only
  195.      transfers data between fields with the same name. If you have
  196.      given different names to the fields in the two forms you will
  197.      have to transfer each individual field separately.
  198.  
  199.      The fields which you create are of four general types - The
  200.      definition (unique) field, grouping fields, ordering fields and
  201.      descriptive fields.
  202.  
  203.      When you create your "Core" data forms it will be fairly
  204.      obvious which is the definition field. In the "Employees" form
  205.      "Worksno" defines the record. In a "Manufacturers" form "Name"
  206.      defines the record. As a general rule, each form should have a
  207.      definition field. There is an exception to this where a form is
  208.      used to store temopary lists (described later) but for the
  209.      moment you should expect to have a definition or "Unique" field
  210.      on each form to prevent duplicate entries. When you create
  211.      secondary forms which lookup data from your "Core" forms the
  212.      data which defines the record as an entity will not necessarily
  213.      be contained solely in one of the fields you wish to display.
  214.  
  215.      As an example - A magazine wholesaler has two "Core" forms, one
  216.      containing details of the magazines he supplies and one
  217.      containing customers details. He creates a form on which to
  218.      record orders from his customers. This "orders" form has three
  219.      fields, "Name"(for the customer), "Magazine" and "Quantity".
  220.      When a customer phones in an order for a particular magazine
  221.      the wholesaler will need to be warned if this particular
  222.      customer has already ordered this particular magazine but no
  223.      one field defines the record. In fact the record is defined as
  224.      unique by a combination of the two fields "Name" and "Magazine"
  225.      In this case, a fourth field should be added to the form in
  226.      which the two fields "Name" and "Magazine" are combined using
  227.      the "jointext" function. This field is then the "Unique" field
  228.      and no duplicate entries will be allowed.
  229.  
  230.      In many secondary forms the records definition will be even
  231.      less obvious but if you are to create data storage for flexible
  232.      reporting you should always attempt to create a suitable
  233.      "unique" field.
  234.  
  235.      For example :- An "Aircraft" form has a field "Manufacturer"
  236.      which is looked up from a "Manufacturers" form. It also has
  237.      fields for "Name" and "Mark". The definition of an aircraft is
  238.      what it is known as. If it has a name then it is known as a
  239.      combination of the manufacturer and the name (Supermarine
  240.      Spitfire) but if it does not have a name it is known as a
  241.      combination of the manufacturer and mark (English Electric P1b)
  242.      Even in these more complicated situations you can still create
  243.      a unique field to prevent duplicates. In the above example you
  244.      would create the unique field "Knownas" and derive it with the
  245.  
  246.  
  247.                                  - 3 -
  248. ................................................................................
  249.  
  250.  
  251.      formula - Jiontext(manufacturer,if(name = blank,mark,name))
  252.  
  253.      When you define a field as unique Easy Base automatically
  254.      indexes this field.
  255.  
  256.      The second type of field is a "Grouping" field. This is a field
  257.      which will be used in procedures to select subsets of records.
  258.      In the "Aircraft" form you might add a field "Type" which would
  259.      qualify each record as belonging to a group - "Fighter",
  260.      "Bomber", "Transport" etc. Grouping fields should also be
  261.      defined as indexed and should always be subject to data
  262.      integrity checking. Where the number of groups is small (17 or
  263.      less) Easy Base provides a quick method of data verification in
  264.      the "Choice" field type. If the number of groups is larger than
  265.      17 then you should create a "Core" form to hold the group names
  266.      and look them up into the secondary form.
  267.  
  268.      The third type of field is used for ordering data. In many
  269.      instances the order in which you wish to print or view data
  270.      will be that of the definition field or one of the grouping
  271.      fields but not always. In the "Aircraft" form you might wish to
  272.      list them by the dates they were first introduced or by the
  273.      total production runs. In order to do this you would have to
  274.      add fields for "Date" and "Production". You would later write
  275.      procedures to list the aircraft with "Date in order" or
  276.      "production in order". Ordering fields should also be indexed
  277.      but they need not necessarily be checked for data integrity.
  278.  
  279.      Fields which are not used for ordering or grouping are
  280.      descriptive and need not be indexed or integrity checked.
  281.  
  282.      One of the most common mistakes made by beginners to data
  283.      management is to create different forms for the same data.
  284.      With the "Aircraft" form above you might be tempted to save all
  285.      the military aircraft of World War 1. Later you might create a
  286.      second form for the aircraft of World War 2. This would be a
  287.      mistake. The data you are recording is "Aircraft". The era to
  288.      which they belong should simply be another "Grouping" field.
  289.      If having saved your data you were asked for a list of all
  290.      "Boeing" military aircraft showing which wars they were used in
  291.      then this could be achieved with one simple procedure if they
  292.      were in one form but would be rather more difficult if they
  293.      were in two.
  294.  
  295.      That example was fairly obvious but on many occasions it will
  296.      be easy to assume that two or more sets of data are separate
  297.      when in fact they are simply groups of the same.
  298.  
  299.      Should you decide to write your own accounting program (Which
  300.      is not as daunting a task as it might seem on the surface) You
  301.      might be tempted to create forms for a Sales Ledger, Nominal
  302.      Ledger and Customers Accounts. In fact the entries in the
  303.  
  304.  
  305.                                  - 4 -
  306. ................................................................................
  307.  
  308.  
  309.      Nominal Ledger and Customers Accounts are simply sub groups of
  310.      the entries in the Sales Ledger. Provided that you include
  311.      grouping fields for the customers account number and nominal
  312.      account name you can construct customers and nominal accounts
  313.      when required by extracting and totalling the sub sets. There
  314.      is no need to save them as separate data.
  315.  
  316.      The final problem you will encounter when deciding how to store
  317.      data is that of "Related Lists".  Consider the "Aircraft" form.
  318.      If you had a grouping for "Airliner" you might wish to record
  319.      all the airlines which operate each aircraft. You cannot just
  320.      add fields to the "Aircraft" form - One airliner might only be
  321.      operated by one airline and another might be operated by fifty.
  322.  
  323.      To store this data you need another form let's call it Userlist
  324.      with fields "Aircraft" , "Airline" and "Uni" which is the
  325.      unique field derived by joining the other two. The "Aircraft"
  326.      field is looked up from the "Aircraft" forms unique field
  327.      "Knownas" and the "Airline" field is looked up from the
  328.      "Airlines" form "Name" field which is also unique.
  329.  
  330.      In this form you enter one record for each combination of
  331.      aircraft and airline. When you come to report on your data you
  332.      can list single records from the main "Aircraft" form together
  333.      with all related records from the "Userlist" form.
  334.  
  335.      ...................PROCEDURE CODE.............
  336.      declare output fields
  337.         aircraft.knownas : Aircraft.production :aircraft.seats
  338.         userlist.airline
  339.      end
  340.      for aircraft with knownas = input.knownas
  341.         print formfields
  342.         for userlist with aircraft = aircraft.knownas
  343.            print userfields
  344.         next
  345.      next
  346.  
  347.      ...................FORMAT.....................
  348.  
  349.      .formfields
  350.                        { Aircraft.knownas field }
  351.  
  352.            Production { Prodn. field}    Seats  {Seats field }
  353.  
  354.                              Operated by :-
  355.  
  356.      .userfields
  357.                       { Userlist.Airline field  }
  358.      .end
  359.  
  360.  
  361.  
  362.  
  363.                                  - 5 -
  364. ................................................................................
  365.  
  366.  
  367.                              FORM DESIGN
  368.  
  369.      To start designing your forms select "Form Design" then "Design
  370.      new Form" from the menu system.  You are presented with a blank
  371.      form. Each form has four pages. To move from one page to the
  372.      next use the PgDn and PgUp keys. To move the cursor around on a
  373.      page use the arrow keys. Designing your form is a bit like
  374.      designing a form on paper. If you were to type on a paper form-
  375.  
  376.               Name     .................
  377.               Address  .................
  378.                        .................
  379.                        .................
  380.                        .................
  381.  
  382.      Then in Easy Base you type Name and Address as above but
  383.      instead of typing the dots you define fields for the data to be
  384.      entered to.
  385.  
  386.      Easy Base provides several facilities for "Polishing" the
  387.      presentation of your forms and these are covered first before
  388.      moving on to field definition.
  389.  
  390.      If you wish to enclose your text within boxes or in some
  391.      tabular format Press F3 and select "Line Drawing".  To draw
  392.      lines on the screen hold down the Alt key, The Ctrl key or both
  393.      and drive the cursor around with the arrow keys. The Alt key
  394.      draws double thin lines, the Ctrl key draws single thin lines
  395.      and a combination of both draws a thick single line. Press Esc
  396.      when you are finished line drawing to return to normal editing.
  397.  
  398.      If you wish to shade areas of the screen then again press F3
  399.      and select "Shading". Shading works much the same as Line
  400.      Drawing.
  401.  
  402.      If you require Greek, Mathematical or International characters
  403.      which cannot be typed directly from the keyboard then press F3
  404.      and select either "Greek and Mathematical" or "International" A
  405.      menu of all such characters provided by your PC will appear.
  406.      The one you select is printed to your form at the cursor
  407.      position.
  408.  
  409.      If you wish to use other than the default text colour then
  410.      press F4 after you have typed your text. In each Easy Base
  411.      screen colour set you can select one of two alternate text
  412.      colours or "Blink" - choose 1, 2 or 3 .  To change the colour
  413.      of your text or lines just hold down the shift key and drive
  414.      the cursor over the text you want to change with the arrow
  415.      keys. Press Esc when you have finished colouring your form.
  416.  
  417.      Text input in the form designer has "overtype" as the default.
  418.      If you wish to move text (or fields) to the right press the
  419.  
  420.  
  421.                                  - 6 -
  422. ................................................................................
  423.  
  424.  
  425.      Ins key. Insert mode is indicated by a block cursor and
  426.      Overtype by an underscore cursor. (This is the opposite to all
  427.      other editors in Easy Base as it keeps the underscore cursor as
  428.      the default)
  429.  
  430.      To insert a blank line above text or fields press F1. You
  431.      cannot scroll text or fields between pages in form design.
  432.  
  433.      If you need to move areas of your form then press F9, shade the
  434.      rectangle you wish to move and move it around with the arrow
  435.      keys. You can also transport the rectangle between pages with
  436.      the PgUp and PgDn keys.  F9 can also be used to erase areas of
  437.      the screen.
  438.  
  439.      When you are ready to define the data fields, position the
  440.      cursor where you want the field to start and press F10.
  441.      A window opens into which you enter all the attributes for the
  442.      field.
  443.  
  444.      The first attribute is "Field Name". If you have typed text to
  445.      the left of the field then Easy Base will have inserted this as
  446.      a default in the Field Name attribute. If it's not the name you
  447.      want just edit it. When you are happy with the field name press
  448.      return or the down arrow to the "Data Type" attribute. A menu
  449.      appears with the nine different field types. (The field types
  450.      are described fully in the Programmers Reference)
  451.  
  452.      When you have chosen a field type the cursor automatically
  453.      moves down to the "Field Length" attribute if you have chosen
  454.      "Text", "Integer", "Fixed Point" or "Floating Point" and to the
  455.      "Mandatory Entry" attribute if you have chosen one of the
  456.      others. Enter the field length you require in characters. If
  457.      you have chosen "Fixed Point" as the field type there are two
  458.      entries, one for the digits left of the decimal point and one
  459.      for the digits right of it. If your field is to hold a currency
  460.      value then the second entry will of course be 2.
  461.  
  462.      You must supply values for the first three field attributes.
  463.      The others all have preset defaults so you can save your field
  464.      at this point if none of the others have to be changed.
  465.  
  466.  
  467.      The next Field Attribute is "Mandatory Entry" which has a
  468.      default of "No".  You can set this to "Yes", "No" or "If". If
  469.      you set it to "Yes" then Easy Base will not allow a record to
  470.      be filed with this field left blank.  If you set it to "If"
  471.      then the "Code Snippet" editor opens up and you can enter the
  472.      condition under which an entry becomes mandatory. If you were
  473.      designing a "Payments" form and one of the fields "Paymethod"
  474.      could be filled with either "Cash" or "Cheque". Then the field
  475.      "ChequeNo" would have to be filled only if the "Paymethod"
  476.      field had "Cheque" entered in it.  To make an entry mandatory
  477.  
  478.  
  479.                                  - 7 -
  480. ................................................................................
  481.  
  482.  
  483.      in the "Chequeno" field only if "Paymethod" is "Cheque" enter -
  484.  
  485.      paymethod = "cheque" in the Code Snippet editor.
  486.  
  487.      When you use the Code Snippet editor for Mandatory Entry and
  488.      for User Entry, only the condition is entered :-
  489.  
  490.            total < 100
  491.            name = blank
  492.            length = blank or breadth = blank
  493.  
  494.      the "if" is assumed.
  495.  
  496.      If you set the "Mandatory Entry" attribute to either "Yes" or
  497.      "If", a window will open into which you can type the message
  498.      which you wish to be displayed should an attempt be made to
  499.      file a blank entry.  If you leave the message blank Easy Base
  500.      will supply the default message "This field must be filled !".
  501.  
  502.      The next attribute is "Unique". This can be set to "Yes" or
  503.      "no".  You can only have one unique field on a form. If you
  504.      have already defined a field as the unique field and you change
  505.      your mind and define another then Easy Base will automatically
  506.      cancel the unique attribute on the first field.  Indexing is
  507.      automatically set to "Yes" for the unique field.
  508.  
  509.      The next attribute is "Indexed". Select "Yes" or "No"
  510.      When you set "Index" to "yes",  Easy Base Creates a separate
  511.      "Index" file in which the contents of the field are kept in up
  512.      to date order. Index files are used by Easy Base in exactly the
  513.      same way that you would use an index in a book to find things
  514.      quickly.
  515.  
  516.      The next attribute is "User entry".  This has a default of
  517.      "Yes" but can be set to "No" or "If".  If you set this
  518.      attribute to "No" then the cursor will not visit the field
  519.      during record entry so the user cannot alter its contents. You
  520.      would normally set this to "No" if the contents are derived or
  521.      calculated from the values of other fields. You can set this
  522.      attribute to "If" if the value entered in another field makes
  523.      this one superfluous. For example, in the "Aircraft" form, if
  524.      you had a field "Passengers" and the type had been entered as
  525.      "Fighter" there would be no point in the cursor moving to the
  526.      "Passengers" field.  When the Code Snippet editor opens you
  527.      could type:-
  528.  
  529.            type = "Transport" or type = "Airliner"
  530.  
  531.      The next field attribute is "Display".   When the cursor
  532.      reaches this attribute a menu appears with the seven different
  533.      ways in which the field can be displayed.
  534.  
  535.  
  536.  
  537.                                  - 8 -
  538. ................................................................................
  539.  
  540.  
  541.      The field display attribute settings have the following
  542.      meaning.
  543.  
  544.      1.  FIELD
  545.  
  546.          The field's size is displayed as a block which shows
  547.          up against the screen background.
  548.  
  549.      2.  TEXT
  550.  
  551.          The field size does not show up against the screen
  552.          background and the contents are in the default text colour.
  553.  
  554.      3.  1ST ALT COL.
  555.  
  556.          As Text but with the contents in the first alternate colour
  557.  
  558.      4.  2ND ALT COL
  559.  
  560.          As Text but with contents in the second alternate colour.
  561.  
  562.      5.  BLINKING
  563.  
  564.          As Text but the contents blink.
  565.  
  566.      6.  INVISIBLE
  567.  
  568.          Neither the size nor the contents can be seen.
  569.          Invisible fields are used to hold compound index fields and
  570.          the results of intermediate calculations which the user
  571.          need not see.
  572.  
  573.      7.  CODEWORD FIELD
  574.  
  575.          The size of a codeword field shows against the screen
  576.          background but its contents are masked by stars.
  577.          Codeword fields are used to collect passwords for
  578.          restricted menus or procedures. An onlooker cannot see the
  579.          password which is being entered.
  580.  
  581.      The final field attribute is "Derived". If you set this to
  582.      "yes" then the Code Snippet editor opens and you can enter the
  583.      formula by which the fields contents are to be derived.
  584.  
  585.      In the Code Snippet editor you can enter almost any derivation
  586.      formula. Formulae consist of field names operators and
  587.      functions.
  588.  
  589.         price * markup
  590.         VATon(net,vatrate)
  591.         datetext(system date)
  592.         if(sex = male,"Mr","Ms")
  593.  
  594.  
  595.                                  - 9 -
  596. ................................................................................
  597.  
  598.  
  599.      All the operators and functions are fully described with
  600.      examples of how they are used in the Programmers Reference.
  601.  
  602.      If in the Code Snippet editor you cannot remember a field or
  603.      function name then Press F1 for the reminder lists.
  604.  
  605.      There is a cut and paste facility in the Code Snippet editor.
  606.      To mark text hold down the shift key and move the cursor with
  607.      the arrow keys. When you release the keys the "Cut" or "Copy"
  608.      choice will appear. To paste text, position the cursor at the
  609.      insertion point and press Shift + Ins.  Text which is cut or
  610.      copied from the derivation of one field can be pasted into the
  611.      derivation of any other field in any other form.
  612.  
  613.      When you have finished entering the field attributes press F2
  614.      to save the field. When you have defined all the fields press
  615.      F2 to save the form.
  616.  
  617.      There is one other facility in the Form Design editor.  If you
  618.      press F5 at any time you enter "Derivation Test Mode".  In
  619.      derivation test mode you can enter data to your fields and
  620.      check if your derivations work correctly.  Any fields which you
  621.      have defined as invisible are not hidden in test mode.  The
  622.      main advantage of test mode as opposed to testing in Record
  623.      Entry comes not when you are designing new forms but when you
  624.      wish to modify one after you have saved many records in it.  If
  625.      you add, delete or alter the length of a field then the entire
  626.      data file has to be reformatted and this takes time.  With
  627.      "Derivation Test Mode" you can ensure that the modifications
  628.      you have made are correct before reformatting.
  629.  
  630.      The only exception to test mode is if you have added a new
  631.      lookup function and you have not yet entered the relationship.
  632.      If you select test mode with a relationship missing you will
  633.      get an error message and be returned to Form Design.
  634.  
  635.      When you save your form Easy Base tests it in derivation test
  636.      mode before saving. If it cannot find a relationship you will
  637.      be given an error message and offered the choice to remain in
  638.      Form Design (which you would do should you know that the
  639.      relationship exists and you must therefore have mistyped a
  640.      lookup formula) or to save and go to the relationships form
  641.      Which you would do if the relationship had not yet been
  642.      entered)
  643.  
  644.      If you opt to go to Relationships Easy Base will transfer you
  645.      to the relationships form and back again via a macro.
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.                                  - 10 -
  654. ................................................................................
  655.  
  656.  
  657.                  RELATIONSHIPS AND THE LOOKUP FUNCTION
  658.  
  659.      In Easy Base the Lookup Function together with pre-recorded
  660.      relationship links provide two of the most important facilities
  661.      of a data management system.
  662.  
  663.          1. Reuse of previously entered data.
  664.          2. Verification of text data.
  665.  
  666.      Consider the situation where you have designed a form to hold
  667.      information about your business's customers. The form has an
  668.      "accountno" field which has been derived as "Sequence" and this
  669.      is therefore the "Unique" field on the form.  It also has
  670.      fields "Name" and "Address".  All your customers have now been
  671.      recorded in this form.  You now want to create an invoice form.
  672.      Each invoice issued will have to have a customer's name and
  673.      address entered on it.  All the names and addresses are already
  674.      filed in Easy Base so they do not have to by typed again.
  675.      Provided that Easy Base knows which customer's name and
  676.      address is required it can copy it automatically from the
  677.      "Customers" form to the "Invoice" form.
  678.  
  679.      The way in which Easy Base accomplishes this is exactly the
  680.      same as you would accomplish the task manually in a hand
  681.      written system. If you knew where to find the book in which
  682.      your customers names had been written and you knew the
  683.      customers account number then you could find the customers name
  684.      and address.
  685.  
  686.      The only slight difference for the computer is that while you
  687.      would consider it "Obvious" that the account number on the
  688.      invoice would be the same as the account number in the
  689.      addresses book your computer does not - You have to tell it.
  690.  
  691.      To tell Easy Base where to look and that the "accountno" is the
  692.      link, you enter a record in the "Relationships" form.
  693.  
  694.      When you select "Relationships" from the main menu you will see
  695.      five fields to be filled.  The first field is the name of the
  696.      form which data is to be copied to. In this case you will enter
  697.      "Invoices".  You will notice that easy base has displayed a
  698.      list of all your form names and that you must choose one.  You
  699.      cannot enter the name freehand.  This "internal" data
  700.      verification is the same as you will be doing for your own data
  701.      later.
  702.  
  703.      The second field is for the name of the form in which the data
  704.      can be found.  In this case select "Customers".
  705.  
  706.      The next two fields record which fields in the primary and
  707.      secondary form hold the "Linking" data. In this case select
  708.      "acountno" in both.
  709.  
  710.  
  711.                                  - 11 -
  712. ................................................................................
  713.  
  714.  
  715.      The final field is the name of the relationship record.  You
  716.      will notice that Easy Base has already entered a default name
  717.      of "Customers".  The relationship name can be anything you like
  718.      but as the "Lookup" function which you are about to use quotes
  719.      the relationship name as its first parameter and the field to
  720.      be copied as its second then Lookup(customers,name) has to be
  721.      more meaningful and easy to remember than any other name you
  722.      could give.
  723.  
  724.      When you have entered all the fields press F2 to save the
  725.      relationship, return to Form Design and load your "Invoice"
  726.      form.
  727.  
  728.      All that remains to do now is edit the field attributes of the
  729.      "Name" and "address" fields.  To edit a field you can either
  730.      press F10 with the cursor on the form background and select the
  731.      field to edit by name, or you can position the cursor within
  732.      the field you wish to edit and then press F10, in which case
  733.      the field attribute window will open automatically.  Position
  734.      the cursor in the "Name" field and press F10. Move the cursor
  735.      to the "Derivation" attribute and set it to yes. (you can move
  736.      the cursor from the "Name" attribute directly to the "Derived
  737.      attribute by pressing the up arrow)
  738.  
  739.      When the Code Snippet window opens type -
  740.  
  741.           Lookup(customers,name)
  742.  
  743.      and press F2.  If you had not already done so then set the
  744.      "User Entry" attribute to "No".
  745.  
  746.      Press F2 to save the new field attributes and then do the same
  747.      for the "Address" field, this time entering the derivation -
  748.  
  749.          Lookup(customers,address)
  750.  
  751.      To test that you have typed the lookups correctly press F5 for
  752.      Derivation Test Mode. Enter a customers account number in the
  753.      "Acountno" field and press the return key. If your formulae are
  754.      correct the customers name and address will appear in the
  755.      "Name" and "Address" fields.
  756.  
  757.      In this example you have performed two "Secondary" lookups.
  758.      Both the "Name" and "Address" fields were found using the
  759.      "accountno" link which you had to enter correctly in order
  760.      to find the other two fields.
  761.  
  762.      The real power of the Lookup function is only realized when you
  763.      perform "Primary" and "Secondary" lookups.  In a "Primary"
  764.      lookup the field whose value is to be looked up is also the
  765.      "Link".  It is "Primary" lookups which are used for data
  766.      integrity checking.
  767.  
  768.  
  769.                                  - 12 -
  770. ................................................................................
  771.  
  772.  
  773.      Consider the "Aircraft" and "Manufacturers" forms which were
  774.      discussed earlier.  Suppose that you want to lookup the
  775.      manufactures name and the name of his base airfield into the
  776.      "Aircraft" form.  The definition field in the "Manufacturers"
  777.      form is "Name" - There is no handy "accountno".  You are going
  778.      to have to enter a relationship between "Aircraft" and
  779.      "Manufacturers" linking the two fields "Manufacturer" in the
  780.      "Aircraft" form with "Name" in the "Manufacturers" form.
  781.  
  782.      Having done this you could derive the "Base" field in the
  783.      "Aircraft" form with - Lookup(manufacturers,base) - and it
  784.      would be looked up when you entered the manufacturers Name just
  785.      as in the invoice example.  But what of the "Manufacturers"
  786.      field itself.  Was the name you entered in the manufacturers
  787.      form "A.V.Roe", "A.V.Roe & Co." or "AVRO A/C Co.".
  788.  
  789.      Easy Base provides a simple solution to this problem.
  790.  
  791.      Having entered the relationship, return to Form design and
  792.      enter the lookup derivations. Derive the "Base" field with -
  793.  
  794.          Lookup(manufacturers,base)
  795.  
  796.      and the "Manufacturers" field with
  797.  
  798.          Lookup(manufacturers,name)
  799.  
  800.      This time, leave the "User Entry" attribute set to "Yes" in the
  801.      "Manufacturers" field.
  802.  
  803.      Press F5 for "Test mode".  When the cursor enters the
  804.      "Manufacturers" field type -  AV*  - and press return.
  805.  
  806.      Provided there is only one manufacturer whose name begins with
  807.      "AV" the Avro name will be looked up into the "Manufacturers"
  808.      field and its representation will always be exactly the same as
  809.      the original entry in the "Manufacturers" form.  If there are
  810.      several manufacturers whose names begin with "AV" then a menu
  811.      will appear listing all of them and you can choose the one you
  812.      want. As soon as you select the name the secondary lookup
  813.      "Base" will fill automatically.
  814.  
  815.      If you cannot remember the first letters of the name you want
  816.      to look up - say for example that you could only remember that
  817.      "Roe" was in the name - then type Roe* and press return.  If
  818.      any manufacturers names begin with "Roe" they will be displayed
  819.      first. If not Easy Base will fill the "Manufacturer" field with
  820.      the first name it finds with the letters roe in it.  If this is
  821.      not the one you want press F3.  Each time you press F3 Easy
  822.      Base will find the next name containing the letters until you
  823.      find the one you want.   As a final resort - if you really
  824.      can't remember what you are looking for - just enter an "*" on
  825.  
  826.  
  827.                                  - 13 -
  828. ................................................................................
  829.  
  830.  
  831.      its own and press return. Easy Base will then list all the
  832.      manufacturers names for you to choose from.
  833.  
  834.      There is no limit to the number of secondary lookups which can
  835.      be made from each primary and there is no limit to the number
  836.      of different forms you can look data up from.
  837.  
  838.      If you have many different forms which all look up data from
  839.      the "Customers" form then they can all use the same
  840.      relationship name "Customers" but if you have more than one
  841.      relationship between the same two forms then they must have
  842.      different names.
  843.  
  844.      If you had a "Stock" form with the unique field "Item" and
  845.      another field "Price" then you could add four fields to your
  846.      "Invoice" form - "Item", "Quantity" "Price" and "Total".
  847.  
  848.      You would enter a relationship "Stock" between "Invoice" and
  849.      "Stock" with the related fields being "Item" in both forms.
  850.  
  851.      In your invoice form you would derive :-
  852.  
  853.         Item as    Lookup(stock,item)
  854.         Price as   Lookup(stock,price)
  855.         Total as   quantity * price
  856.  
  857.      When you entered the "Item" field (primary lookup) the price
  858.      field would fill automatically and when you entered the
  859.      "Quantity" the "Total" field would be calculated.
  860.  
  861.      However, if you now add four more fields "Item2", "Price2",
  862.      "Quantity2" and "Total2" you will need another relationship
  863.      between "Invoice" and "Stock" this time linking "Item2" in the
  864.      "Invoice file" with "Item" in the stock file and you cannot now
  865.      use the default name "Stock" for the relationship.
  866.  
  867.      Although you can give your additional relationship any name you
  868.      like, the best name will be "Stock2".
  869.  
  870.      Please note that this example is used purely to show the use of
  871.      multiple relationships between the same two forms.  If you are
  872.      intending to write an invoicing system then unless you know
  873.      that there will only be a limited number of items on each
  874.      invoice this is not a practical way to tackle the problem.
  875.  
  876.      In a flexible invoicing system each item and quantity is
  877.      entered via a procedure to a temporary list form whose contents
  878.      are then printed to the invoice.
  879.  
  880.      From V9 the lookup function also accepts a third parameter with
  881.      which you can specify the display of a field other than that
  882.      which is being looked up. See "Lookup" in Programmers Reference
  883.  
  884.  
  885.                                  - 14 -
  886. ................................................................................
  887.  
  888.  
  889.                                DATA ENTRY
  890.  
  891.      As soon as you have designed forms you can enter and view data
  892.      directly using the default screen you created.  To enter data
  893.      to a form select "Data Entry" from the main menu and choose the
  894.      form you wish to use.
  895.  
  896.      Your default entry screen will appear with the cursor in the
  897.      top left field. The top line of the screen shows the name and
  898.      page number of the form you are using together with the system
  899.      date and time. Line 2 shows the number of the record you are
  900.      creating or editing on the left hand side. It is also the line
  901.      on which any error messages are passed. The bottom line lists
  902.      the most used function keys and is also the line on which help
  903.      prompts are displayed.
  904.  
  905.      To move the cursor around between fields you can use all of the
  906.      cursor control keys which work as follows:-
  907.  
  908.      The Return key moves from field to field in the order top left
  909.      to bottom right unless you have overridden this in form design
  910.      by deriving fields with "Goto (fieldname) Next".
  911.  
  912.      The Tab key moves the cursor from field to field in the order
  913.      bottom right to top left (reverse of Return).
  914.  
  915.      The arrow keys move the cursor in the direction indicated.
  916.  
  917.      The Home Key moves the cursor to the beginning of the current
  918.      field if it is not already there and to the first field on the
  919.      page if it is.
  920.  
  921.      The End Key moves the cursor to the end of text if it is in a
  922.      text field and to the last field on the page if it is not.
  923.  
  924.      The PgUp and PgDn Keys move between pages if your form has more
  925.      than one.
  926.  
  927.      When you have entered the data for your first record press F2
  928.      to save it to disk. The screen will clear, the message "Record
  929.      1 has been added" will appear briefly on line two and you will
  930.      be ready to enter the next record.
  931.  
  932.      If some of your fields are primary lookups then you use them
  933.      exactly the same as was described for "Derivation Test Mode" by
  934.      entering part of the text followed by a star and pressing the
  935.      Return Key.
  936.  
  937.      Once you have saved a few records to disk you may wish to view
  938.      or edit them. You can bring previously entered records back to
  939.      the screen for editing in several ways.  From record creation
  940.      the F5 Key brings up the first record and subsequent presses
  941.  
  942.  
  943.                                  - 15 -
  944. ................................................................................
  945.  
  946.  
  947.      bring up the next record. Similarly, from record creation the
  948.      F4 Key brings up the last record and subsequent presses bring
  949.      up the previous record.
  950.  
  951.      Once you have entered several records this process becomes
  952.      impracticable and you "search" for the record you wish to view
  953.      or edit.  Position the cursor in any field and type part of the
  954.      field contents you wish to search for followed by a star and
  955.      press F3.
  956.  
  957.      Searching for records within a form is a similar process to
  958.      looking up data except that you press the F3 rather than the
  959.      Return Key to initiate the process. If the field in which you
  960.      are searching is indexed and more than one record matches the
  961.      data you have entered then Easy Base will make a list of all
  962.      the field contents which match for you to choose from.  If the
  963.      field is not indexed then Easy Base will bring up the first
  964.      record it finds a match in. If this is not the record you want
  965.      then press F3 again. Easy Base will find another match on each
  966.      successive press of the F3 key until you find the record you
  967.      want. As with lookups, Easy Base will search for "Part Matches"
  968.      after it has exhausted all the records where the entered data
  969.      matches the beginning of the field and if you enter a star on
  970.      its own and press F3, Easy Base will list all the field
  971.      contents for you to choose from.
  972.  
  973.      When you have brought a previously entered record back to the
  974.      screen you will notice that line 2 now displays "Editing Record
  975.      x of y " rather than "Creating New Record x ".  Easy Base
  976.      automatically changes from "Create" to "Edit" mode when you
  977.      view a record.  The changes which you make on screen are not
  978.      entered to the record on disk until you press F2.
  979.  
  980.      To clear the contents of the field in which the cursor lies
  981.      rather than delete each character press F6. To return to
  982.      "Create" mode press F6 twice.
  983.  
  984.      Not all of the active function keys are listed on the prompt
  985.      line. To see a full menu of the function key uses press F1 for
  986.      the Function Key Menu.  The following is a summary of the
  987.      function key usage in Data Entry:-
  988.  
  989.      F1
  990.  
  991.      The F1 Key brings up the function key Menu.
  992.  
  993.      F2
  994.  
  995.      The F2 Key writes a new record from "Create" and updates the
  996.      record on screen from "Edit" mode.
  997.  
  998.  
  999.  
  1000.  
  1001.                                  - 16 -
  1002. ................................................................................
  1003.  
  1004.  
  1005.      F3
  1006.  
  1007.      The F3 key initiates searches for previously entered records
  1008.      based on the data entered in the current field.
  1009.  
  1010.      F4
  1011.  
  1012.      The F4 key moves to the previous record when in "Edit" mode and
  1013.      to the last record from "Create" mode.
  1014.  
  1015.      F5
  1016.  
  1017.      The F5 Key Moves to the next record when in "Edit" mode and to
  1018.      the first record from "Create" mode.
  1019.  
  1020.      F6
  1021.  
  1022.      The F6 key clears the current field on the first press and
  1023.      returns you to "Create" mode on the second press.
  1024.  
  1025.      F7
  1026.  
  1027.      The F7 key deletes the record currently on screen in "Edit"
  1028.      mode.  When you delete a record with the F7 key it is not
  1029.      actually erased from the disk. It is simply "Flagged" for
  1030.      deletion at the next "Pack" operation. If you delete a record
  1031.      accidentally you can reinstate it any time before the form is
  1032.      next packed.
  1033.  
  1034.      F8
  1035.  
  1036.      The F8 key creates a new record by copying the record currently
  1037.      on screen. If a new record you wish to create contains similar
  1038.      data to one already entered then you can find the previous
  1039.      entry, change the unique field and copy it with F8 rather than
  1040.      type it all again.
  1041.  
  1042.      F9
  1043.  
  1044.      If you know the number of the record you wish to view or edit
  1045.      you can press F9 and enter the record number. Easy Base will
  1046.      then bring the record whose number you have entered to the
  1047.      screen.
  1048.  
  1049.      F10
  1050.  
  1051.      When you press the F10 key Easy Base searches for records which
  1052.      are "Flagged" for deletion.  When it finds one it will bring it
  1053.      to the screen. You can reinstate a deleted record by pressing
  1054.      F2 while it is on screen. The F5 key searches for the next
  1055.      deleted record and the Escape key returns you to "Live
  1056.      Records".
  1057.  
  1058.  
  1059.                                  - 17 -
  1060. ................................................................................
  1061.  
  1062.  
  1063.      F11
  1064.  
  1065.      F11 prints the record on screen exactly as formated for the
  1066.      screen at 10 CPI. Some printers cannot print 80 characters at
  1067.      10 CPI so avoid using the last three screen columns.
  1068.  
  1069.      F12
  1070.  
  1071.      The F12 key brings up the form's "Options". There are four
  1072.      options in Data Entry.
  1073.  
  1074.         1. Clear screen on Adding Record.             (Default Yes)
  1075.         2. Confirmation Required to delete Records.   (Default Yes)
  1076.         3. Confirmation Required to abandon Edits     (Default No)
  1077.         4. Clear Field on Editing                     (Default No)
  1078.  
  1079.      If you change "Clear Screen on adding Record" to "No" then,
  1080.      when you press F2 to file a new record, the data which is
  1081.      written to disk remains on screen ready for the next new
  1082.      record. This is useful if you are entering several records and
  1083.      many of the fields in each record contain the same data. You
  1084.      only have to overwrite the fields which are different each
  1085.      time.
  1086.  
  1087.      If you have many records to delete then set option 2 to "No"
  1088.      and you will be able to delete them without having to confirm
  1089.      each one.
  1090.  
  1091.      If you set option 3 to "Yes" then Easy Base will ask you to
  1092.      confirm that you wish to leave a record which you have edited
  1093.      but not updated to disk.
  1094.  
  1095.      If you set option 4 to "Yes" then Easy Base will clear the
  1096.      old contents of any field you start to edit.  This is most
  1097.      useful when used in conjunction with option 1. You can file a
  1098.      record, retain the contents for the next record and when you
  1099.      edit the fields which are different you do not have to first
  1100.      delete the data in them.
  1101.  
  1102.      The options you set for any given form remain with it until
  1103.      changed. They do not revert to the defaults when your computer
  1104.      is turned off and each form can have different option settings.
  1105.  
  1106.      Ctrl + E
  1107.  
  1108.      If you press the "E" key while holding down the Ctrl key you
  1109.      will get the extended "Greek" and "International" characters
  1110.      menu which was discussed in form design.
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.                                  - 18 -
  1118. ................................................................................
  1119.  
  1120.  
  1121.      Ctrl + S
  1122.  
  1123.      If you press The "S" key while holding down the Ctrl key you
  1124.      start the Spell-checker.  The Spell-checker will check the
  1125.      current field. If it finds a word not included in the Easy base
  1126.      dictionary it will offer you the choices to leave the word and
  1127.      continue, add the word to the dictionary, or choose one of the
  1128.      suggestions for replacement.
  1129.  
  1130.      The Spell checker does not automatically move from field to
  1131.      field but once you have started it, it remains active and will
  1132.      immediately check the next text field you move the cursor to.
  1133.  
  1134.      The Spell-checker is cancelled if you press the Escape key or
  1135.      if you press the F2 key to update the record.
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.                                  - 19 -
  1176. ................................................................................
  1177.  
  1178.  
  1179.                         PROCEDURES (REPORTING)
  1180.  
  1181.      The Easy Base procedure generator is the means by which you
  1182.      manipulate and report on your data.
  1183.  
  1184.      Each procedure has at least one part, the procedure code.  The
  1185.      procedure code contains the instructions you write to tell Easy
  1186.      Base what you want done.
  1187.  
  1188.      If your procedure has an "output", in other words your
  1189.      instructions tell Easy Base to send data to the screen or to
  1190.      the printer, then the procedure must also have an Output
  1191.      Format. The Output Format is where you show Easy Base how you
  1192.      want the data you are about to "output" arranged on the screen
  1193.      or page.
  1194.  
  1195.      If what your procedure is to do depends on variables, ie it
  1196.      requires information from the operator or from Looked up data
  1197.      from one or more of your forms then it also requires an "Input
  1198.      Screen".  The Input Screen is where you gather the variable
  1199.      information that your procedure needs in order to carry out its
  1200.      task.
  1201.  
  1202.      Select "procedures" from the main menu and have a look at the
  1203.      items on the procedures menu.
  1204.  
  1205.      You will notice that the menu has pre-selected item 2 "Load
  1206.      Existing Procedure". Other than your first procedure this is
  1207.      the most useful starting point.  Item 1, "Create New Procedure"
  1208.      is only required if you wish to start a new procedure after you
  1209.      have another one loaded. The three parts to a procedure
  1210.      mentioned above are created and edited at items 3,4 and 5.
  1211.  
  1212.      Procedures, like forms, are saved to disk and can be re-used
  1213.      repeatedly. Item 6 runs the current procedure and item 7 saves
  1214.      it to disk.
  1215.  
  1216.      Item 8 deletes procedures which are no longer required and Item
  1217.      9 copies an existing procedure. Often you will require a
  1218.      procedure which is similar to one you have already created. It
  1219.      is much quicker to copy the first procedure and then edit it
  1220.      than to start a new procedure from scratch.
  1221.  
  1222.      Item 10 recalls the last output from a procedure to the screen.
  1223.      If you need to see the output from a procedure but it is not
  1224.      imperative that you have the most up to date information,
  1225.      (close of business / month end figures Etc) then it is much
  1226.      quicker to view the last output than to re-run the procedure.
  1227.  
  1228.      Finally, a small window just below the menu shows the name of
  1229.      the currently loaded procedure. In this case it is "Untitled".
  1230.  
  1231.  
  1232.  
  1233.                                  - 20 -
  1234. ................................................................................
  1235.  
  1236.  
  1237.      If you have not already done so, read the descriptions of the
  1238.      Declare, For..Next, If..Then, Print and Printer Control
  1239.      commands in the Programmers Reference now. These are the basis
  1240.      of all "reporting" procedures and should be thoroughly
  1241.      understood. If you are a programming beginner then some of the
  1242.      examples in the For..Next section may seem a bit advanced -
  1243.      Just ignore them - for the moment it is only important that you
  1244.      understand the principle of the loop and the qualifications
  1245.      that can be applied to it.
  1246.  
  1247.      Now select item 4 to write your first Procedure Code.
  1248.      The next few pages will describe simple reporting procedures
  1249.      based on the "Aircraft" form. To write like procedures for the
  1250.      forms you have designed all you have to do is substitute your
  1251.      form and field names.
  1252.  
  1253.      Before you start, have a look at the function key list on the
  1254.      bottom line. F2 saves your code and checks it. If you press the
  1255.      Escape key your code is still saved but the checking routine is
  1256.      bypassed. If you have written code and find that it is not
  1257.      passed on F2 because, for example, one of your form fields
  1258.      needs to be indexed, then you can still save the code you have
  1259.      written while you modify the form.
  1260.  
  1261.      F3 and F4 provide search and replace facilities similar to a
  1262.      word processor.
  1263.  
  1264.      There is a cut and paste system.  To mark code for cutting or
  1265.      copying hold down the Shift key and shade the code with the
  1266.      arrow keys.  As soon as you release the keys a menu will pop up
  1267.      with three options - Cut, Copy or Indent. The cut and copy
  1268.      options work exactly the same as in the Code Snippet editor
  1269.      with Shift + Ins used to paste the text. If you select "Indent"
  1270.      then you can indent all the selected lines at once with the
  1271.      left and right arrow keys.
  1272.  
  1273.      If you want to print out your code then press F10.
  1274.  
  1275.      The F1 key, labelled "Help" is the key you use when you can't
  1276.      remember something.  It has all the names of your forms, the
  1277.      names of the fields in each form and the names of all Commands,
  1278.      functions, and System values.  If Easy Base recognizes the
  1279.      context of your procedure when you press F1 then it will list
  1280.      the names you need (Formnames, fieldnames or Commands). If not
  1281.      a menu will appear from which you can pick which you need.
  1282.  
  1283.      With the cursor at the start of the top line on your blank
  1284.      procedure screen press F1.
  1285.  
  1286.      The "Commands" reminder list appears on the right hand side of
  1287.      the screen.  The command you want is the first one , "Declare
  1288.      Output Fields" but before selecting it have a look at how to
  1289.  
  1290.  
  1291.                                  - 21 -
  1292. ................................................................................
  1293.  
  1294.  
  1295.      select from the reminder lists. There are over fifty commands
  1296.      on this list but only the first seventeen are shown. You can
  1297.      scroll though them with the arrow keys but you can also use the
  1298.      inbuilt alphabetic search facility. If you type "o" then the
  1299.      highlight bar will move directly to the "Odd Page Print"
  1300.      command.
  1301.  
  1302.      Take the highlight bar back to the "Declare Output Fields"
  1303.      command either by scrolling or by pressing the Home key and
  1304.      press return.  The command will be inserted on the first line,
  1305.      the cursor will move to the second line and the "Forms"
  1306.      reminder list will appear.  Select the form which you wish to
  1307.      report on. In my example case this will be "Aircraft".
  1308.      "Aircraft." is inserted on the second line and the "fields"
  1309.      reminder list appears. I select "Knownas".  I also wish to list
  1310.      the aircraft's mark and type so I write.
  1311.  
  1312.      Declare output fields
  1313.         Aircraft.knownas : Aircraft.mark : Aircraft.type
  1314.      end
  1315.  
  1316.      Declare the fields you wish to list either by typing them
  1317.      freehand or by pressing F1 for reminders.
  1318.  
  1319.      Now complete your procedure code:-
  1320.  
  1321.      Declare Output fields
  1322.         Aircraft.knownas : Aircraft.mark : Aircraft.type
  1323.      end
  1324.      for Aircraft
  1325.         Print list items
  1326.      next
  1327.  
  1328.      and press F2 to check and save the code.
  1329.  
  1330.      If you have typed everything correctly you will be returned to
  1331.      the Procedures menu.  If you have misspelled something then the
  1332.      line with the error will be highlighted and you will get an
  1333.      error message. Correct the error and press F2 again.
  1334.  
  1335.      Easy Base now knows that it is to list the three fields
  1336.      Knownas, Mark and Type from all the records in the "Aircraft"
  1337.      form.  It does not know how they are to be arranged or whether
  1338.      they are to be printed or just shown on screen. This
  1339.      information must now be recorded on the procedures "Output
  1340.      Format".
  1341.  
  1342.      Select item 5, "Output Format", from the procedures menu and
  1343.      have a look at the screen. As usual the bottom line shows the
  1344.      function key usage. To insert a blank line you use F1 as in
  1345.      form design. F2 saves the format and the Escape Key abandons
  1346.      it. F3 gives you a line drawing facility similar to that in
  1347.  
  1348.  
  1349.                                  - 22 -
  1350. ................................................................................
  1351.  
  1352.  
  1353.      form design and Ctrl + "E" brings up the Greek and
  1354.      International characters menu.  The F10 Key is used to place
  1355.      your output fields.
  1356.  
  1357.      The upper status line shows the paper size you have selected at
  1358.      the left hand edge. If you scroll to the right it also shows
  1359.      where the right hand edge of your paper will be at the three
  1360.      different print sizes 10, 12, and 17 characters per inch.
  1361.  
  1362.      On the right hand side of the screen a small menu will have
  1363.      appeared offering you a choice of Format Section names. You do
  1364.      not have to use one of these they are just to save you time.
  1365.      For the moment select "List Items" from this menu.
  1366.  
  1367.      .List items  will appear on the first line and the cursor will
  1368.      move to the second.  For a first procedure we will simply list
  1369.      the fields required in columns. To do this move the cursor in
  1370.      along the second line to leave a reasonable margin and press
  1371.      F10 to place the first field.  A menu appears listing the three
  1372.      fields which were declared in the procedure's code. I select
  1373.      "Aircraft.knownas".  As soon as The field has been selected a
  1374.      window opens showing the default type and length of the field.
  1375.      You can change these defaults if you wish the printed length or
  1376.      type(for numeric fields) to be different in the report to what
  1377.      it is in the form. This window also presents an extra attribute
  1378.      marked "Trim Trailing Spaces" which defaults to "No". If you
  1379.      set this to "Yes" then any blanks at the beginning or end of
  1380.      the fields contents will not be printed at run time. This
  1381.      facility is used mainly for inserting numbers or names into
  1382.      form letter text.
  1383.  
  1384.      Press F2 to accept the defaults. The area which the field will
  1385.      occupy is shown on screen. Now move the cursor to the right and
  1386.      place the other two fields. Finally, press the return key to
  1387.      take the cursor to a new line and type a full stop ".".  The
  1388.      section names menu appears again.  This time select "End".
  1389.  
  1390.      The format screen now looks like this.
  1391.  
  1392.      .List Items
  1393.           ██████████████    ████████████   ████████████
  1394.      .End
  1395.  
  1396.      Press F2 to save the format. When you do, a new menu will pop
  1397.      up with four choices for the output destination. The exact
  1398.      meanings of these selections will be discussed shortly.  For
  1399.      the moment select "Output to Screen". When the Procedures menu
  1400.      appears select item 7 and save your procedure to disk.
  1401.  
  1402.      Now select item 6 and run the procedure.
  1403.  
  1404.      The fields from each record of the "Aircraft" form are listed
  1405.  
  1406.  
  1407.                                  - 23 -
  1408. ................................................................................
  1409.  
  1410.  
  1411.      down the screen. When the list reaches the bottom line the
  1412.      screen starts to scroll.  When all records have been listed the
  1413.      screen returns to the start of the list from where you can
  1414.      browse the report. If the list is long you can pause the output
  1415.      by pressing the return key while it is still running. Once the
  1416.      report is complete you can browse through it using the PgUp,
  1417.      PgDn and arrow keys.  You can also use the text search facility
  1418.      at F3.
  1419.  
  1420.      When you have finished reading the report press Escape to
  1421.      return to the procedures menu.  You can browse the report again
  1422.      at any time by selecting item 10 (Recall Last Output). Try it
  1423.      now.  While browsing a report you can also print it out by
  1424.      pressing F10.  If you press F10 to print a report from browse
  1425.      mode you invoke a low level print driver which prints the
  1426.      report at 10 CPI, 6 LPI in draft mode. Other font sizes and
  1427.      effects such as Bold and Underline are only available when you
  1428.      direct the report output to the printer at run time.
  1429.  
  1430.      To try printer effects select "Edit Procedure Code" and change
  1431.      The code to:-
  1432.  
  1433.      Declare output fields
  1434.         Aircraft.knownas : Aircraft.mark : Aircraft.type
  1435.      end
  1436.      Bold on
  1437.      12 CPI
  1438.      for aircraft
  1439.         print list items
  1440.      next
  1441.  
  1442.      Save the new code and select "Edit Output Format". There is
  1443.      nothing to change in the format itself but when you press F2 to
  1444.      save it, this time choose "Choose at Run time" for the output
  1445.      destination.
  1446.  
  1447.      When you now select "Run Procedure", the computer will beep and
  1448.      you will be asked whether the output is to be to the screen or
  1449.      printer. Choose printer and easy base will print your report in
  1450.      bold at 12 characters to the inch. (Assuming you have installed
  1451.      the correct printer driver from the utilities menu)
  1452.  
  1453.      You will notice that while Easy Base was printing your report
  1454.      it also output it to the screen but on completion it returned
  1455.      you to the procedures menu without invoking Browse mode.
  1456.  
  1457.      The output destinations which you choose when saving the output
  1458.      format are not "Either or" choices.  Irrelevant of your choice
  1459.      the output is always sent to both the screen and the disk file.
  1460.      It is the disk file that you browse when you select "Recall
  1461.      Last Output".  The differences between the choices are that
  1462.      only an output to the screen invokes Browse mode on completion
  1463.  
  1464.  
  1465.                                  - 24 -
  1466. ................................................................................
  1467.  
  1468.  
  1469.      and only an output to printer prints the report. Output to disk
  1470.      is only selected if you want to update reports from a Batch
  1471.      Execute menu.
  1472.  
  1473.      Now let's try something a bit more interesting. So far the
  1474.      report simply lists the aircraft in the order in which the
  1475.      records were filed.  To list them in alphabetic order, edit the
  1476.      procedure code and change the "For" line to:-
  1477.  
  1478.      for aircraft with knownas in order
  1479.  
  1480.      Save the code.  Easy Base can only list in order if the field
  1481.      you wish the order to be done by is indexed.  If the field you
  1482.      have chosen is not indexed you will get an error message.  If
  1483.      this happens, save the code by pressing the Escape Key - Save
  1484.      the procedure at item 7 then return to form design.  Load your
  1485.      form - edit the attributes for the field changing Indexed to
  1486.      "Yes".
  1487.  
  1488.      You can now reload your procedure and run it. This time the
  1489.      aircraft names will be in alphabetic order.
  1490.  
  1491.      Because a procedure has up to three parts it may not at this
  1492.      stage be obvious how Easy Base is handling the "Saving" or
  1493.      "Abandoning" of separate parts.  Here is a quick explanation.
  1494.      If you escape from either the output format or later the input
  1495.      screen and choose to "abandon" it you are abandoning it in the
  1496.      version of the report you are editing only. If you escape from
  1497.      the procedures menu and choose to "abandon" the procedure then,
  1498.      if it is a new "Untitled" procedure it is lost but if it is a
  1499.      procedure which you have loaded for editing then it is only the
  1500.      edits which are abandoned - The original procedure remains
  1501.      unchanged on disk. A procedure which you have loaded for
  1502.      editing is only changed on disk when you save it with item
  1503.      seven from the procedures menu.  At any time during the editing
  1504.      of a procedure you can throw away all your edits and return to
  1505.      the original version by reloading it from disk and replying
  1506.      "No" when you are asked if you wish to save the currently
  1507.      loaded version.
  1508.  
  1509.      Suppose now that we wished to list the aircraft in groups by
  1510.      type - all the bombers together - all the fighters together
  1511.      Etc.
  1512.  
  1513.      To do this, edit the procedure code again and change the "For"
  1514.      line to: -
  1515.  
  1516.      for aircraft with type in order
  1517.  
  1518.      This time, when the report is run, all the airliners come first
  1519.      followed by the bombers etc. but the group field "Airliner" ,
  1520.      "Bomber" etc. is listed on each line and it would be much
  1521.  
  1522.  
  1523.                                  - 25 -
  1524. ................................................................................
  1525.  
  1526.  
  1527.      neater if it could be separated or printed in Bold or
  1528.      underline.
  1529.  
  1530.      Edit the code again, this time to:-
  1531.  
  1532.      Declare output fields
  1533.         Aircraft.knownas : Aircraft.mark : Aircraft.type
  1534.      end
  1535.      declare variables
  1536.        lasttype as text
  1537.      end
  1538.      for Aircraft with type in order
  1539.         if aircraft.type <> lasttype then print group header
  1540.         lasttype = aircraft.type
  1541.         print list items
  1542.      next
  1543.  
  1544.      In this code we have introduced a text variable "lasttype".
  1545.      During the "For" loop the list items will be printed on each
  1546.      iteration but the group header will only be printed when the
  1547.      type changes
  1548.  
  1549.      Now edit the output format to:-
  1550.  
  1551.      .group header
  1552.  
  1553.          ████████████████
  1554.      .list items
  1555.                  ███████████████     ██████████████
  1556.      .end
  1557.  
  1558.      The group header starts with a blank line which will separate
  1559.      the groups. It contains only the "Type" field.  The list items
  1560.      section contains the "Knownas" and mark fields.
  1561.  
  1562.      When you run this report the output will be:-
  1563.  
  1564.         Airliners
  1565.                 Boeing 707
  1566.                 Dehaviland Comet     Mk4
  1567.                 Boeing Jumbo Jet     747
  1568.  
  1569.         Bombers
  1570.                 Boeing B52
  1571.                 Avro Vulcan
  1572.                 Avro lancaster       2
  1573.  
  1574.  
  1575.      If you want the group header to be in bold or underline then
  1576.      all you have to do is insert the on and off commands before and
  1577.      after the "Print group header" command using the block If then
  1578.      construction.
  1579.  
  1580.  
  1581.                                  - 26 -
  1582. ................................................................................
  1583.  
  1584.  
  1585.      Declare output fields
  1586.         Aircraft.knownas : Aircraft.type : Aircraft.mark
  1587.      end
  1588.      declare variables
  1589.         lasttype as text
  1590.      end
  1591.      for Aircraft with type in order
  1592.         if aircraft.type <> lasttype then
  1593.            bold on : underline on
  1594.            print group header
  1595.            bold off : underline off
  1596.         end if
  1597.         print list items
  1598.      next
  1599.  
  1600.      As a beginner, you are probably wondering about the reason for
  1601.      the indentations after the "for" and "if" lines. The code will
  1602.      work perfectly well without them. When you come to write more
  1603.      advanced procedures you will have many For loops, Do Loops and
  1604.      If conditions interwoven with each other.  If each has its own
  1605.      indentation then you will be able to see at a glance which
  1606.      commands occur within which loops and conditions and your code
  1607.      will be very easy to read and edit.
  1608.  
  1609.      Going back to the "Aircraft" listing procedure, we now have
  1610.      each group separated but the aircraft names themselves are no
  1611.      longer in alphabetic order.  This is because we changed index
  1612.      files when we selected "With Type in order".  It is now the
  1613.      "Type" groupings which are in alphabetic order.  Suppose that
  1614.      we want to keep this grouping but still list the aircraft in
  1615.      each group with their names in order.  Neither of the index
  1616.      files on the "Knownas" or "Type" fields can produce this order.
  1617.      We need a combined or "Compound" index on both fields
  1618.  
  1619.      To construct this index, save the present procedure and return
  1620.      to form design.  Load the "Aircraft" form and add a new field
  1621.      anywhere on it. Assuming the length of the "Knownas" field as
  1622.      45 and the length of the "Type" field as 14 the new fields
  1623.      attributes are:-
  1624.  
  1625.      Name         Typename
  1626.      Type         Text
  1627.      Length       59
  1628.      Mandatory    No
  1629.      Unique       No
  1630.      Indexed      Yes
  1631.      User Entry   No
  1632.      Display      Invisible
  1633.      Derived      Yes
  1634.  
  1635.      The derivation formula is:-
  1636.      Jointext(spacepad(type,15),knownas)
  1637.  
  1638.  
  1639.                                  - 27 -
  1640. ................................................................................
  1641.  
  1642.  
  1643.      Test that the derivation formula is correct by pressing F5 for
  1644.      test mode. When you type a name into the "Knownas" field and a
  1645.      type in the "Type" field the new field should derive as a
  1646.      combination of the two.
  1647.  
  1648.      Escape from test mode and press F2 to save the form. Easy Base
  1649.      will first re-format the data file to incorporate the new field
  1650.      and then write the new index file.
  1651.  
  1652.      When this is complete, return to the procedure and edit the
  1653.      "For line of the code from:-
  1654.  
  1655.      For aircraft with type in order
  1656.  
  1657.      to
  1658.  
  1659.      For Aircraft with typename in order
  1660.  
  1661.      No change is necessary to the output format.  The output will
  1662.      be laid out as before but the names in each group will be in
  1663.      alphabetic order.
  1664.  
  1665.      To "Polish" the "Aircraft" report it would be nice if it had a
  1666.      heading. We would also like to prevent the list from running
  1667.      off the end of the page when printed and add a page number at
  1668.      the foot of each page.
  1669.  
  1670.      To do these things edit the code to:-
  1671.  
  1672.      Declare output fields
  1673.         Aircraft.knownas : Aircraft.type : Aircraft.mark
  1674.         page number                  'New Field
  1675.      end
  1676.      Declare variables
  1677.         lasttype as text
  1678.      end
  1679.      bold on
  1680.      print report header
  1681.      for aircraft with typename in order
  1682.         if bottom margin < 1 then
  1683.            bold on : print page footer
  1684.            page feed : print page header : bold off
  1685.         end if
  1686.         if aircraft.type <> lasttype then
  1687.            bold on : underline on
  1688.            print group header
  1689.            bold off : underline off
  1690.         end if
  1691.         print list items
  1692.      next
  1693.      print report footer
  1694.  
  1695.  
  1696.  
  1697.                                  - 28 -
  1698. ................................................................................
  1699.  
  1700.  
  1701.      Now edit the output format to:-
  1702.  
  1703.      .Report header
  1704.          ════════════════════════════════════════════════════
  1705.                      AIRCRAFT LIST BY TYPE
  1706.          ────────────────────────────────────────────────────
  1707.      .Group Header
  1708.  
  1709.          ████████████████
  1710.      .List Items
  1711.                  ████████████████     ██████████████████
  1712.      .Page header
  1713.          ════════════════════════════════════════════════════
  1714.                   Aircraft List By Type (Cont)
  1715.          ────────────────────────────────────────────────────
  1716.      .Page Footer
  1717.  
  1718.                              - ██ -
  1719.      .Report Footer
  1720.          ════════════════════════════════════════════════════
  1721.      .End
  1722.  
  1723.      The new print sections Report Header, Report Footer, and Page
  1724.      Header contain only fixed text.  The new section Page Footer
  1725.      contains the new field "page number" and the "Trim trailing
  1726.      spaces" attribute should be set to "Yes" in this.  This will
  1727.      keep the correct spacing of   - 9 -    and   - 10 -    when the
  1728.      page numbers are printed.
  1729.  
  1730.  
  1731.      So far all the fields we have printed are from the same form
  1732.      "Aircraft".  Suppose that we also wanted to list the country of
  1733.      origin for each aircraft.  The "Aircraft" form does not hold
  1734.      this information but the "Manufacturers" form has a field
  1735.      "Nationality". To incorporate this field into the report all we
  1736.      have to do is declare it as an output field and then arrange to
  1737.      have that field in memory when we print the list items. We can
  1738.      load the correct record from the "Manufacturers" form by using
  1739.      the linking data "Name" in the manufacturers form and
  1740.      "Manufacturer" in the "Aircraft" form.  This is a similar
  1741.      process to looking up data except that a pre defined
  1742.      relationship is not necessary. We can tell Easy Base exactly
  1743.      what we want within the code.
  1744.  
  1745.      Declare output fields
  1746.         Aircraft.knownas : Aircraft.type : Aircraft.mark
  1747.         Manufacturers.nationality : Page number
  1748.      end
  1749.      Declare variables
  1750.         Lasttype as text
  1751.      end
  1752.  
  1753.  
  1754.  
  1755.                                  - 29 -
  1756. ................................................................................
  1757.  
  1758.  
  1759.      '.....................PRINT REPORT HEADING...
  1760.      print report header
  1761.      '.................
  1762.      for aircraft with typename in order
  1763.         '..................PRINT HEADERS AND FOOTERS...
  1764.         if bottom Margin < 1 then
  1765.            bold on : print page footer
  1766.            page feed : print page header : bold off
  1767.         end if
  1768.         '..................PRINT GROUP HEADERS.........
  1769.         if aircraft.type <> lasttype then
  1770.            bold on : underline on
  1771.            print group header
  1772.            bold off : underline off
  1773.         end if
  1774.         '...............LOAD MANUFACTURERS NATIONALITY..
  1775.         for manufacturers with name = aircraft.manufacturer
  1776.            Print list items
  1777.         next
  1778.         '..............
  1779.      next
  1780.      print report footer
  1781.  
  1782.      Because the procedure code is becoming longer, remarks are
  1783.      added to make it easier to see which parts of the code do what.
  1784.      You can add remarks to your code anywhere by prefixing them
  1785.      with an apostrophe.
  1786.  
  1787.      At the point where we are about to print the list items we
  1788.      start another "For" loop.  This time "For Manufacturers".  When
  1789.      one "For" loop is "Nested" within another, the record currently
  1790.      loaded by the first loop remains in memory while the records
  1791.      selected by the "Nested" loop are processed and all the fields
  1792.      of both records are available at the same time.
  1793.  
  1794.      As we have qualified the "Manufacturers" loop:-
  1795.  
  1796.      for manufacturers with name = aircraft.manufacturer
  1797.  
  1798.      only the single record in which the "Name" field matches the
  1799.      "Aircraft.manufacturer" field which is currently loaded by the
  1800.      outer loop will be selected from the "Manufacturers" form.
  1801.  
  1802.      While we have both the required records in memory we print the
  1803.      list items.
  1804.  
  1805.      All that remains to do now is to edit the output format and add
  1806.      the "Manufacturers.nationality" field to the .List Items
  1807.      section.
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.                                  - 30 -
  1814. ................................................................................
  1815.  
  1816.  
  1817.      By nesting loops in this way, you can list data from any number
  1818.      of different forms which have "Linking" data in one of their
  1819.      fields.  Where only one record matches as in the example above
  1820.      then the required fields go in the .List items section with the
  1821.      other fields.  Where there are many matches (Related list) the
  1822.      fields from the secondary loop have their own print section.
  1823.      (See example on page 5)
  1824.  
  1825.      Now we can print any of the fields from any "Related" forms in
  1826.      any order.  We are still, however, listing all the records from
  1827.      the "Aircraft" form and we may for example only wish to print
  1828.      those records which are in the "Bomber" group.
  1829.  
  1830.      Start a new procedure and enter the code:-
  1831.  
  1832.      Declare output fields
  1833.         Aircraft.knownas : Aircraft.type : Aircraft.base
  1834.      end
  1835.      for aircraft with type = "Bomber"
  1836.         print list items
  1837.      next
  1838.  
  1839.      Create the output format placing the three output fields within
  1840.      the .List Items section.
  1841.  
  1842.      When you run this report, only the bombers will be listed but,
  1843.      once more, the aircraft names will be in the order in which
  1844.      they were entered to the form.
  1845.  
  1846.      To get them in alphabetic order we must again use the compound
  1847.      index on the "Typename" field. This time we have to ensure that
  1848.      the loop starts with the first "Bomber" and ends with the last
  1849.      "Bomber".
  1850.  
  1851.      Declare output fields
  1852.         Aircraft.knownas : Aircraft.type : Aircraft.base
  1853.      end
  1854.      declare variables
  1855.         group as text
  1856.      end
  1857.      group = "Bomber"
  1858.      for aircraft with typename > "Bomber"
  1859.         if aircraft.type <> group then exit for
  1860.         print list items
  1861.      next
  1862.  
  1863.      Before starting the "For" loop we set a variable "Group" to the
  1864.      value "Bomber". The "For" loop is then qualified such that the
  1865.      records will be processed with "Typename" in order but starting
  1866.      with the first occurrence of "Bomber" in the field.  To stop
  1867.      the loop when all the bombers have been processed we test the
  1868.      contents of the "Aircraft.type" field on each iteration of the
  1869.  
  1870.  
  1871.                                  - 31 -
  1872. ................................................................................
  1873.  
  1874.  
  1875.      loop and when the first record is loaded which is not a bomber
  1876.      we stop processing the loop with the command "Exit For".
  1877.  
  1878.      As in the first procedure, we could now add Page headers, Page
  1879.      footers and number the pages Etc.
  1880.  
  1881.      Suppose however that having created this procedure we now
  1882.      wanted a list of all the "Airliners".
  1883.  
  1884.      We could achieve this by changing "Bomber" to "Airliner" within
  1885.      the code but this would be time consuming. It would be much
  1886.      better if we could tell Easy Base which type group we wanted at
  1887.      the start of the procedure and have Easy Base make the
  1888.      necessary changes.
  1889.  
  1890.      To supply "Variables" to a procedure before running we use an
  1891.      "Input Screen", the third part of a procedure.  Save the code
  1892.      and select item 3 (Create Input Screen) from the procedures
  1893.      menu.
  1894.  
  1895.      As soon as you select item 3 Easy Base will ask if you wish to
  1896.      copy an existing form. Type "N" for no.  The next screen will
  1897.      be familiar to you.  It is exactly the same as the form design
  1898.      screen.
  1899.  
  1900.      When you first designed your forms, the form design routine
  1901.      performed two tasks. It created your form and also a default
  1902.      input screen from which to enter data. Now that you are about
  1903.      to create input screens for procedures, the same routine is
  1904.      used to design the screen.  It does not, of course, create a
  1905.      parallel form.
  1906.  
  1907.      All the facilities for "Polishing" your forms - all the
  1908.      facilities for deriving, calculating looking up and testing
  1909.      derivations which you had in Form Design are also available for
  1910.      Input Screen design.
  1911.  
  1912.      The only difference you will notice is that when you define a
  1913.      field, the "Unique" and "Indexed" attributes are marked "Not
  1914.      Applicable" and when you run the procedure, only the "Options"
  1915.      "Clear Screen after Running Procedure" and "Clear Field on
  1916.      Editing" are available.
  1917.  
  1918.      Move the cursor to somewhere near the middle of the screen and
  1919.      type:- "Which Aircraft type would you like listed".  Then press
  1920.      F10 to define a field.
  1921.  
  1922.      If, in the aircraft form the "Type" field had been defined as a
  1923.      choice field, then we would define this field as a choice field
  1924.      and use the same list.
  1925.  
  1926.      If, on the other hand the "Type" field in the "Aircraft" form
  1927.  
  1928.  
  1929.                                  - 32 -
  1930. ................................................................................
  1931.  
  1932.  
  1933.      looked up its contents from a core data form containing the
  1934.      type names then we would set the attributes:-
  1935.  
  1936.      Name            type
  1937.      Data type       text
  1938.      Field Length    15    (Same as the "Type" field in "Aircraft")
  1939.      Mandatory       Yes
  1940.      User Entry      Yes
  1941.      Display         Field  (or text or Alt colours as you wish)
  1942.      Derived         No
  1943.  
  1944.      The field will of course be derived:- Lookup(Aircraft,type)
  1945.      but as we have not yet entered the relationship, we will leave
  1946.      the derived attribute set to "No" to prevent an error message
  1947.      when we save the screen.
  1948.  
  1949.      Save the screen.  When you do, you will be asked to select
  1950.      between "Repeat Screen after F2" and "Run Once and Exit".
  1951.  
  1952.      If you choose the first option then the procedure will repeat
  1953.      until you press the Escape Key. If you choose the second
  1954.      option, control will return to the procedures menu after the
  1955.      report has been run.
  1956.  
  1957.      Now save the procedure.  Let's call it "Aircraft By Type".
  1958.  
  1959.      You may have noticed that all Form, Field and Procedure names
  1960.      so far have been single words.  There is no restriction on
  1961.      using multiple words in names but single ones make code much
  1962.      easier to read. The only good reason to use more than one word
  1963.      is in a reporting procedure name. After the procedure has been
  1964.      run the status line in Browse mode will be "Procedure:-
  1965.      Aircraft By Type" which makes more sense to an end user than
  1966.      "Procedure:- ACbytyp".
  1967.  
  1968.      Now go to Relationships and enter the relationship "Aircraft"
  1969.      between "Aircraft by Type" and "Aircraft" linking the two
  1970.      fields "Type".
  1971.  
  1972.      Reload the "Aircraft by Type" procedure and edit the Input
  1973.      screen setting the derived attribute to "yes" and entering the
  1974.      derivation formula:-  Lookup(aircraft,type)
  1975.  
  1976.      Save the screen again and select "Edit Procedure Code".
  1977.  
  1978.      To use the Input screen quickly you could change the two
  1979.      occurrences of "Bomber" to input.type. However, now that we
  1980.      have an input.type field the variable "group" is superfluous.
  1981.  
  1982.      The finished procedure code and Output format are shown on the
  1983.      next page.
  1984.  
  1985.  
  1986.  
  1987.                                  - 33 -
  1988. ................................................................................
  1989.  
  1990.  
  1991.      Declare output fields
  1992.         Aircraft.knownas : Aircraft.base
  1993.         Page number : input.type
  1994.      end
  1995.      Print report header
  1996.      for aircraft with typename > input.type
  1997.         if bottom margin < 1 then
  1998.            print report footer
  1999.            page feed : print page header
  2000.         end if
  2001.         if aircraft.type <> input.type then exit for
  2002.         print list items
  2003.      next
  2004.      print report footer
  2005.      page feed
  2006.  
  2007.  
  2008.      ......................Output Format.........
  2009.  
  2010.      .Report Header
  2011.             ══════════════════════════════════════════════
  2012.                           ████████████ LIST
  2013.                           ════════════
  2014.                 Name                   Built at
  2015.             ──────────────────────────────────────────────
  2016.      .Page header
  2017.             ──────────────────────────────────────────────
  2018.                 Name                   Built at
  2019.             ──────────────────────────────────────────────
  2020.      .List items
  2021.                 ████████████████████   █████████████████
  2022.      .Page Footer
  2023.  
  2024.                              - ██ -
  2025.      .Report Footer
  2026.             ══════════════════════════════════════════════
  2027.      .End
  2028.  
  2029.  
  2030.      The field in the Report header is input.type.  The fields in
  2031.      the list items are Aircraft.knownas and Aircraft.base.
  2032.      The field in the page footer is Page number.
  2033.  
  2034.      Suppose now that we print out the report and find that we had
  2035.      entered all the "Aircraft" "Knownas" fields in Upper case and
  2036.      all the "Base" fields in Lower case.  This would make the
  2037.      report quite untidy.  There is no need however to change the
  2038.      original data. To print both fields in Upper case all we need
  2039.      to do is alter each of the "Base" field contents using the
  2040.      "Upper" Function before printing it.
  2041.  
  2042.      To do this insert the line:-
  2043.  
  2044.  
  2045.                                  - 34 -
  2046. ................................................................................
  2047.  
  2048.  
  2049.         aircraft.base = upper(aircraft.base)
  2050.  
  2051.      immediately before the print list items command.
  2052.  
  2053.      As well as simply "Listing" data you can manipulate it in many
  2054.      different ways.  You can do any form of arithmetic on numeric
  2055.      fields and you can alter text, date and time fields with over
  2056.      fifty different functions.
  2057.  
  2058.      A function is a small internal routine which returns a value
  2059.      derived from one or more other values (Parameters) which you
  2060.      supply.  For Example, in the code line:-
  2061.  
  2062.      date = datetext(invoice.date)
  2063.  
  2064.      "Datetext" is a function to which you are passing the parameter
  2065.      "Invoice.date".  If invoice.date is 02/02/94 then the function
  2066.      "Datetext" will derive the text "2nd February 1994" and
  2067.      "Return" this as if it were a variable. The output field "Date"
  2068.      will therefore become "2nd February 1994".
  2069.  
  2070.      A functions parameters are always passed to it enclosed in
  2071.      brackets.  If there are more than one then they are separated
  2072.      by commas.
  2073.  
  2074.      The next section of the Manual introduces you to Procedures
  2075.      which perform transactions.  You should now read the
  2076.      descriptions of the following commands in the Programmers
  2077.      Reference.
  2078.  
  2079.      Copy All From
  2080.      Delete Record
  2081.      Clear Records From
  2082.      Update Record
  2083.      Pause On/Off
  2084.      Escape On/Off
  2085.  
  2086.      Together with the field control "Beep".
  2087.  
  2088.      Note:
  2089.  
  2090.      From Version 7 Procedures with input screens can be innitiated
  2091.      with any of the function keys 2,4,5,,7,8,9 or 10
  2092.  
  2093.      See Programmers Ref. Procedure command "Run"
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.                                  - 35 -
  2104. ................................................................................
  2105.  
  2106.  
  2107.                      PROCEDURES (TRANSACTIONAL)
  2108.  
  2109.      In Data Entry you make a "Transaction" when you add, update or
  2110.      delete a record.  You can make the same transactions in
  2111.      procedures.  There are, however, two major advantages to
  2112.      making your transactions via procedures.
  2113.  
  2114.      1.   You control which transactions can and cannot be made.
  2115.  
  2116.      2.   You can make any number of different transactions in any
  2117.           number of different forms.
  2118.  
  2119.      Consider the "Customers" form.  You would want any of your
  2120.      staff to be able to add a new customer in your absence. If you
  2121.      allow them to do this in Record Entry then they could also
  2122.      (deliberately or inadvertently) alter or delete other customers
  2123.      records.
  2124.  
  2125.      To prevent this, create a new procedure.  Create an input
  2126.      screen.  When you are asked if you wish to copy an existing
  2127.      form - reply "Yes" and select the customers form.  Save the
  2128.      input screen and select Create Procedure Code. Now enter the
  2129.      procedure code:-
  2130.  
  2131.      for customers new record
  2132.         copy all from input
  2133.      next
  2134.  
  2135.      Save the procedure - Let's call it "Enter customers".  You can
  2136.      now call this procedure from your "User Menus" described in the
  2137.      next section and your staff will be able to enter new customers
  2138.      without the opportunity to make any other transactions.
  2139.  
  2140.      You can also control parts of a transaction.  If your
  2141.      "Customers" form had a field for "Creditlimit" then, in the
  2142.      form, you would wish to be able to enter any credit limit you
  2143.      wanted, but you might wish to restrict the amount your staff
  2144.      could enter for a new customer.
  2145.  
  2146.      To do this you simply edit the field attributes for the
  2147.      "Creditlimit" field in the input screen.
  2148.  
  2149.      To set a fixed credit limit of say £500.00 set the user entry
  2150.      attribute to "No", the derived attribute to "Yes" and enter the
  2151.      derivation formula:- 500.
  2152.  
  2153.      To restrict the entry to a maximum of say £1000.00 you would
  2154.      leave the user entry attribute set to "yes" but derive the
  2155.      field:-  If(creditlimit > 1000,blank[beepMaximum credit £1000
  2156.               for new customers],creditlimit)
  2157.  
  2158.      There might also be fields on the "Customers" form which are
  2159.  
  2160.  
  2161.                                  - 36 -
  2162. ................................................................................
  2163.  
  2164.  
  2165.      irrelevant to the transaction of adding a new customer.  You
  2166.      might also have fields for personal comments which you do not
  2167.      wish your staff to see.  You can simply delete these from the
  2168.      input screen or change them to invisible.
  2169.  
  2170.      In other words you can limit a transaction in any way you wish
  2171.      and the final input screen can be totally different to the
  2172.      original form.
  2173.  
  2174.      Transaction procedures which delete or update records are
  2175.      created in a similar manner but are slightly more complicated.
  2176.  
  2177.      To create a procedure which allows your staff to delete
  2178.      customers, you would again copy the customers form as the input
  2179.      screen.  This time, the only field to which you allow User
  2180.      Entry is the "acountno" field.  You enter a relationship
  2181.      between this report and the "Customers" form linking "acountno"
  2182.      and derive all the other fields you wish to show as:-
  2183.  
  2184.      lookup(customers,name)
  2185.      lookup(customers,address)
  2186.      Etc.
  2187.  
  2188.      Your staff now enter the account number to be deleted. The
  2189.      other "looked up" fields are only there so that the name and
  2190.      address will appear confirming that the correct account number
  2191.      has been entered.
  2192.  
  2193.      The procedures code to delete the record is:-
  2194.  
  2195.      for customers with acountno = input.acountno
  2196.         delete record
  2197.      next
  2198.  
  2199.      As with the procedure to add a record you are still in complete
  2200.      control of what can or cannot be done.  Suppose that you had a
  2201.      field on the "customers" form which you kept updated with his
  2202.      account balance.  You would not want anyone to delete a
  2203.      customer who still had an outstanding balance on his account.
  2204.  
  2205.      To prevent this, just change the derivation for the "balance"
  2206.      field to :-
  2207.  
  2208.      if(lookup(customers,balance) <> 0,blank[beepCustomers cannot be
  2209.      deleted until their A/C is clear],0)
  2210.  
  2211.      You would also set the Mandatory attribute to "Yes" to prevent
  2212.      anyone from ignoring the warning.
  2213.  
  2214.      If you wanted a procedure which allowed staff to change a
  2215.      customers address but no other fields, then you would create
  2216.      the same input screen as for the delete record and the same
  2217.  
  2218.  
  2219.                                  - 37 -
  2220. ................................................................................
  2221.  
  2222.  
  2223.      relationship but this time you would allow user entry to the
  2224.      address field and derive it:-
  2225.  
  2226.      Default(lookup(customers,address))
  2227.  
  2228.      When the operator enters the account number for the customer
  2229.      whose address he wishes to change, the old address will appear
  2230.      to confirm that he has the right customer, but he will be able
  2231.      to edit it.
  2232.  
  2233.      The procedure code would be:-
  2234.  
  2235.      for customers with acountno = input.accountno
  2236.         customers.address = input.address
  2237.         update record
  2238.      next
  2239.  
  2240.      The second advantage of making transactions via procedures is
  2241.      that you can perform several tasks at once. Consider a Video
  2242.      Library hiring films to its members. There will be a form for
  2243.      the films, one for the members and one for daily takings.
  2244.  
  2245.      The procedure used for hiring out the films will have an input
  2246.      screen with a field for the members number, possibly three
  2247.      fields for the film numbers being hired, three more fields in
  2248.      which the films rental prices are looked up and one in which
  2249.      these three fields are totalled.  When the operator runs the
  2250.      procedure all the necessary transactions are performed by the
  2251.      procedure code:-
  2252.  
  2253.      for members with number = input.member
  2254.         if input.film1 <> blank then members.film1 = input.film1
  2255.         if input.film2 <> blank then members.film2 = input.film2
  2256.         if input.film3 <> blank then members.film3 = input.film3
  2257.         update record
  2258.      next
  2259.      if input.film1 <> blank then
  2260.         for films with number = input.film1
  2261.            films.hiredto = input.member
  2262.            films.datehired = system date
  2263.            update record
  2264.         next
  2265.      end if
  2266.      for daily takings
  2267.         total = total + input.total
  2268.         update record
  2269.      next
  2270.  
  2271.      The mid section of the code updating film1's record would of
  2272.      course be repeated for film2 and film3 but has been omitted for
  2273.      clarity.
  2274.  
  2275.  
  2276.  
  2277.                                  - 38 -
  2278. ................................................................................
  2279.  
  2280.  
  2281.                             USER MENUS
  2282.  
  2283.      Once you have created forms and procedures you can create an
  2284.      end user menu system to run them.  You could wait till all your
  2285.      procedures are finished but you will get a much better feel for
  2286.      how your program is developing if you start and use a menu
  2287.      system as you go.  Easy Base includes a User Menu call to its
  2288.      system menus so you can work from your own developing menu
  2289.      system while you are still developing your program.
  2290.  
  2291.      Select "Menus" from the main menu and have a look at the
  2292.      screen.  The Menus screen is an internal form just like the
  2293.      ones you have created. You have all the same facilities to
  2294.      enter, update and delete menus that you have in Data Entry to
  2295.      one of your own forms.
  2296.  
  2297.      Let's create a menu based on some of the forms and procedures
  2298.      previously discussed.
  2299.  
  2300.      The first field on the menus form is "Menu Name".  This is the
  2301.      unique field and a name must be supplied.  We'll call it
  2302.      "Customers".  The next field is "Menu Type". This is a choice
  2303.      field with two options, "Normal" and "Batch Execute".  The
  2304.      "Batch Execute" option will be discussed later.  For now,
  2305.      select "Normal".
  2306.  
  2307.      The third field is "Menu Title". Whatever you enter here will
  2308.      be displayed as a title (or heading) above your menu.
  2309.  
  2310.      The fourth field which is untitled on the screen is a choice
  2311.      field with the options, "Run on Number Key" and "Run on Return
  2312.      Key".  If you choose the first option then the items on your
  2313.      menu will be run as soon as the item number is pressed and if
  2314.      you choose the second option then typing the item number will
  2315.      move the highlight bar to the selection but the item will not
  2316.      be called until the return key is pressed.  In either case you
  2317.      will still be able to select items with the cursor control keys
  2318.  
  2319.      The next field asks for a "Sign on password" if a startup menu.
  2320.      You can start your application (program) on any menu that has
  2321.      a sign on password by restarting Easy Base and using that
  2322.      password instead of your developers password.  In this case we
  2323.      are going to menu the reports which add, delete and alter a
  2324.      customers address. This will be a sub menu so we leave this
  2325.      field blank.
  2326.  
  2327.      The main section of the "Menus" form has three columns of nine
  2328.      fields.  The first column is for the text to be displayed on
  2329.      the menu.  The second is for the type of action (function)
  2330.      which is to be called.  The third is for the individual item.
  2331.  
  2332.  
  2333.  
  2334.  
  2335.                                  - 39 -
  2336. ................................................................................
  2337.  
  2338.  
  2339.      With the cursor in the first text field we type:-
  2340.  
  2341.      Enter a New Customer      and press return.
  2342.  
  2343.      As soon as the cursor moves to the first "Function" field a
  2344.      menu appears listing all the different functions that can be
  2345.      called.  The first four choices allow you to:-
  2346.  
  2347.      1.   Run one of your procedures.
  2348.      2.   Recall the last output from one of your procedures.
  2349.      3.   Call the data entry screen for one of your forms.
  2350.      4.   Call another of your menus.
  2351.  
  2352.      The other functions are selected utilities from the system
  2353.      utilities menu which you may wish to provide to the
  2354.      end user without allowing him access to the entire system.
  2355.  
  2356.      Select "Run Procedure" and press return.
  2357.  
  2358.      When the cursor moves to the "Item" column Easy Base will list
  2359.      all your procedures. Choose "Enter customers".
  2360.  
  2361.      on the next two lines enter:-
  2362.  
  2363.      Delete Existing Customer   Run Procedure    Delete Customers
  2364.      Change Customers Address   Run Procedure    Address Change
  2365.  
  2366.      and press F2 to save the menu.
  2367.  
  2368.      Now let's make a start to the main "Startup" menu.  We may not
  2369.      have any procedures to put on it yet but we can get started
  2370.      with an item to call data entry to "Customers" and one to call
  2371.      the "Customers" sub menu.
  2372.  
  2373.      Fill in a new menus record using the name "Main Menu", Type
  2374.      "Normal" and Title "- M A I N   M E N U -".  This time enter a
  2375.      startup password, say "Fred".  Complete the Items section
  2376.      with:-
  2377.  
  2378.      Customers Records          Data Entry       Customers
  2379.      Customer Updates           User Menu        Customers
  2380.      Program Development        System menus
  2381.  
  2382.      Press F2 to save this menu then press escape all the way out to
  2383.      the DOS prompt (or your hard disk menu system).  Restart Easy
  2384.      Base.  This time, when the sign on screen appears, enter "Fred"
  2385.      and press return.
  2386.  
  2387.      Instead of the system menus, you will see your "Main Menu".
  2388.      If you select item 1 the "Customers" form will come up. If you
  2389.      select item 2 your sub menu will be overlaid and you can run
  2390.      any of the three procedures on it.  If you select item 3 you
  2391.  
  2392.  
  2393.                                  - 40 -
  2394. ................................................................................
  2395.  
  2396.  
  2397.      will be transferred to the Easy Base System menus where you can
  2398.      continue with the development of your program.
  2399.  
  2400.      Whenever you create new procedures or forms you can add them to
  2401.      your menu system.
  2402.  
  2403.      Suppose you would like the utilities, Backup Data, Restore Data
  2404.      and Install Printer to be available from your menu system.
  2405.      Create a new menu, let's call it "Utilities" with the items:-
  2406.  
  2407.      Backup data to disk        Backup Data
  2408.      Restore data from disk     Restore Data
  2409.      Install Printer            Install Printer
  2410.  
  2411.      Save this new menu then edit your main menu to include the new
  2412.      item:-
  2413.  
  2414.      Utilities                  User menu           Utilities
  2415.  
  2416.      When you have called the Easy Base system menus from one of
  2417.      your own menus then pressing escape does not exit the program,
  2418.      it returns you to your own menu.  You close down by pressing
  2419.      escape from your main menu.  When you get back to your "Main
  2420.      Menu" you will notice that the new "Utilities" item is not
  2421.      there. New Menu items cannot be added while the program is
  2422.      running. To incorporate the "Utilities" item you must again
  2423.      exit the program and restart with the password "Fred".
  2424.  
  2425.      As your program develops you can create as many menus as you
  2426.      need. Your "Main Menu" can call up to nine sub menus. Each of
  2427.      those can call another nine sub sub menus Etc Etc. You can also
  2428.      have additional startup menus with different passwords. These
  2429.      can either run completely different menus or can restrict
  2430.      different parts of the menu system to different users.
  2431.  
  2432.      When you start up on one of your menus systems Easy Base
  2433.      creates a default "Tree" structure for it.  From whichever menu
  2434.      is on screen the escape key backsteps down the tree until you
  2435.      reach your "Main Menu" and then exits the program.
  2436.  
  2437.      If one of the "forward" menu calls crosses branches, ie it
  2438.      calls a menu which is also called from a lower level then
  2439.      subsequent presses of the escape key backstep down the current
  2440.      branch and not back "cross tree".
  2441.  
  2442.      You can also make menu calls from low to high levels. (a sub-
  2443.      sub- sub menu can have an item which calls the main menu).
  2444.  
  2445.      In some circumstances you may prefer a hierarchical rather than
  2446.      a tree structure where the main menu is recalled after each
  2447.      individual procedure.  To accomplish this, each final item is
  2448.      placed on its own menu followed by a call to the main menu and
  2449.  
  2450.  
  2451.                                  - 41 -
  2452. ................................................................................
  2453.  
  2454.  
  2455.      the menu type is changed to "Batch Execute".
  2456.  
  2457.      When you create a "Batch Execute" menu then instead of
  2458.      displaying a menu for you to choose from, Easy Base
  2459.      executes each item on the menu in sequence and then returns to
  2460.      the menu which called it.
  2461.  
  2462.      With batch execute menus you can automate many of the processes
  2463.      in your application.  If you have several printouts to be done
  2464.      each day you can have them all done from batch execute menus.
  2465.      Similarly, if you need to update many reporting procedures for
  2466.      later "Recall" to the screen, these can all be done at once.
  2467.      There is no limit to the number of procedures which can be
  2468.      batched - One batch menu can call another.
  2469.  
  2470.      If you create a "Startup" batch menu then, provided it does not
  2471.      call a "Normal" menu, Easy Base will perform all the tasks on
  2472.      the menu and then exit to DOS.
  2473.  
  2474.      If you create a "Startup" batch menu which eventually calls a
  2475.      "Normal" menu then the batch process stops at that point and
  2476.      the "Normal" menu becomes the main (root) menu.  Pressing
  2477.      escape from this menu exits to DOS. it never returns to the
  2478.      startup batch menu which called it
  2479.  
  2480.      Start up batch menus are useful for running regular daily
  2481.      procedures and for forcing the user to check the system date
  2482.      and time.
  2483.  
  2484.      There are many other uses for batch execute menus.  You can
  2485.      automate menu changes. If, for example, running one particular
  2486.      procedure is invariably followed by  running one from a choice
  2487.      of three others then the menu containing the others can be
  2488.      batched after the first procedure.
  2489.  
  2490.      In Easy Base you can create quite long and complex procedures
  2491.      but they are eventually limited by memory constraints.  If you
  2492.      ever run out of memory creating a long procedure then just
  2493.      split it and batch the parts.
  2494.  
  2495.      Don't forget to set the output of non print reports to "Disk"
  2496.      otherwise Browse Mode will be invoked.
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.  
  2508.  
  2509.                                  - 42 -
  2510. ................................................................................
  2511.  
  2512.  
  2513.                       EXTERNAL FILE ACCESS
  2514.  
  2515.      In order to provide flexible import and export to data files
  2516.      external to your applications, Easy Base includes a complete
  2517.      set of low level file access commands. :- Open, Close, Seek
  2518.      Read, Write, Find, Shell and Erase.
  2519.  
  2520.      Full details of the commands and how to use them are given in
  2521.      the programmers reference but please read the following notes.
  2522.  
  2523.      You can only open one external file at a time but you can
  2524.      transfer data either way between it and any number of Easy Base
  2525.      files.
  2526.  
  2527.      You can open any number of external files within one procedure
  2528.      but you must close each before you open the next.
  2529.  
  2530.      In Easy Base all data is converted to a common type for
  2531.      processing. Within the system this has the advantage that you
  2532.      never need to worry about what type of data you are handling.
  2533.      You can assign a text field's value to a numeric field and you
  2534.      can assign the result of a calculation to a text field.
  2535.      However, in order to do this Easy Base pre processes text
  2536.      variables. If you are accustomed to file access, string
  2537.      manipulation and trimming functions then you may get unexpected
  2538.      results.
  2539.  
  2540.      Here are the rules:
  2541.  
  2542.      If you read a string to an Easy Base text field all leading and
  2543.      trailing spaces are removed. If the remaining string is longer
  2544.      than the declared field length then it is truncated to the
  2545.      field length.
  2546.  
  2547.      If you read a string to an Easy Base text variable then all
  2548.      trailing spaces are removed. Text Variables are variable
  2549.      length.
  2550.  
  2551.      If you wish to create a string with leading spaces for a write
  2552.      command then you must do it in a text variable. Text fields do
  2553.      not accept leading spaces. You can pad strings with spaces
  2554.      using the Spacepad and Jointext(stringof()) functions.
  2555.  
  2556.      If you read an ASCII line then it is read without the Cr/Lf
  2557.      sequence.
  2558.  
  2559.      You can read ASCII directly into numeric fields.
  2560.  
  2561.      The data in an Easy Base Text Block field is formatted with a
  2562.      single Chr$(13) wherever a new line is to be forced.
  2563.  
  2564.      To read ASCII to a Text Block field, read lines to a variable
  2565.  
  2566.  
  2567.                                  - 43 -
  2568. ................................................................................
  2569.  
  2570.  
  2571.      then join the variable to the field with an intervening
  2572.      CHr$(13).
  2573.  
  2574.      Ex.
  2575.      read line to LineVar
  2576.      Pupils.notes = Jointext(pupils.notes,Chr$(13),Linevar)
  2577.  
  2578.      To Write a Text Block field as ASCII lines use the keyword
  2579.      Line_Len in the write command.
  2580.  
  2581.      Ex.
  2582.      write Pupils.Notes Line_len 60
  2583.  
  2584.      You cannot write quotation marks within quoted text. Whenever
  2585.      Easy Base processes a text field, variable or read in string it
  2586.      substitutes Chr$(127) for internal quotation marks and replaces
  2587.      them after the process. This substitution is not done for
  2588.      direct assignments. TextVar = "Fred said "Hello"" is not
  2589.      allowed. If you need to make such an assignment then you must
  2590.      replace the internal quotation marks with Chr$(127) yourself.
  2591.      To create CHR$(127) in the procedure editor, hold down the ALT
  2592.      key and type 127 on the numeric keypad.
  2593.  
  2594.  
  2595.  
  2596.  
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.                                  - 44 -
  2626. ................................................................................
  2627.  
  2628.  
  2629.                     EASY BASE DATA FILE FORMAT
  2630.  
  2631.      Easy Base data files are fixed length record files with no
  2632.      field separator. There is no file header.
  2633.  
  2634.      There is a three byte record header. Byte one is "L" for a live
  2635.      record and "D" for a record marked for deletion. Bytes 2 and 3
  2636.      are null.
  2637.  
  2638.      The field order is top left to bottom right from the default
  2639.      input screen.
  2640.  
  2641.      All text fields are ASCII.
  2642.  
  2643.      All numeric, date and time fields are Microsoft 8 Byte double
  2644.      precision numbers.
  2645.  
  2646.      In the case of dates, this represents the number of days from
  2647.      the first of January 1981 and in the case of time, the number
  2648.      of seconds from midnight.
  2649.  
  2650.  
  2651.  
  2652.  
  2653.  
  2654.  
  2655.  
  2656.  
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.  
  2663.  
  2664.  
  2665.  
  2666.  
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672.  
  2673.  
  2674.  
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.                                  - 45 -
  2684. ................................................................................
  2685.  
  2686.  
  2687.                          SYSTEM REQUIREMENTS
  2688.      Required.
  2689.  
  2690.          IBM or compatible 286 or higher
  2691.          1Meg Ram
  2692.          540k free conventional memory   (570k in Network Version)
  2693.  
  2694.  
  2695.      Preferred.
  2696.  
  2697.         4 Meg expanded memory with 2 Meg allocated to PC-Cache
  2698.  
  2699.      NOTE:-
  2700.         If you have 2 Meg of expanded memory then certain EMS
  2701.      managers can cause Easy Base not to load with the error message
  2702.      "Insufficient EMS to load overlays". If this happens to you
  2703.      then you can load Easy Base in conventional memory by remming
  2704.      out the EMS driver in your Config.Sys file.
  2705.  
  2706.                          SYSTEM LIMITATIONS
  2707.  
  2708.      Fields per Form         500
  2709.      Indexes per Form        500
  2710.      Record Length           Limited by display of 4 screen pages
  2711.      Records per Form        Limited by Maximum data or index file
  2712.                              length of 2,100 Megabytes
  2713.  
  2714.      Forms per application       }     Total of 500 in
  2715.      Procedures per application  }     any combination.
  2716.      Menus per application             500
  2717.  
  2718.  
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.  
  2729.  
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.                                  - 46 -
  2742. ................................................................................
  2743.  
  2744.  
  2745.                        DOS FILENAME CONVENTIONS
  2746.  
  2747.      The Easy Base system files are:-
  2748.  
  2749.         EB.EXE     The program file     (EB.OVL Network)
  2750.         EB.CUR     Initial screen setup
  2751.         EB.SET     Configuration file   (EB.C0, EB.C1 Etc. Network)
  2752.         EB.MEN     User Menus form
  2753.         EB.REL     Relationships form
  2754.         EB.MSG     Text and error messages
  2755.         EB.PRS     Printer drivers
  2756.         EB.D01     Main dictionary
  2757.         EB.DO2     Personal dictionary
  2758.  
  2759.      The files which are created in the data directories have the
  2760.      following filename convention:-
  2761.  
  2762.      Forms:-
  2763.  
  2764.         BASE(No).DEF      The entry screen definition.
  2765.         BASE(No).DAT      The data file.
  2766.         BASE(No).(No)     Index files.
  2767.  
  2768.      Choice field lists
  2769.  
  2770.         LIST(No).DAT
  2771.  
  2772.      Procedures
  2773.  
  2774.         PROC(No).PRO      The procedure code.
  2775.         PROC(No).DEF      The input screen.
  2776.         PROC(No).REP      Procedure output (Pre Network Versions)
  2777.         PROC(No).R(No)    Procedure output (Network versions)
  2778.  
  2779.      There are also six individual files:-
  2780.  
  2781.         MENUS.DAT         The menus you create.
  2782.         RELATION.DAT      The relationships you create.
  2783.         CHOICES.DIR       The choice list directory.
  2784.         BASE.DIR          The forms directory.
  2785.         PROC.DIR          The procedures directory.
  2786.         RECOVER.INF       Recovery information to reinstate a form
  2787.                           should you suffer a power failure during
  2788.                           a pack or reformat operation.
  2789.  
  2790.      From V9 each form and procedure input screen also has a pre
  2791.      processed file: BASE(NO).PPR - PROC(NO).PPR.
  2792.  
  2793.      From Network V1 Private data and index files take the main file
  2794.      name overstamped from the second character by the terminal
  2795.      number. The file name for Terminal 12's private data for
  2796.      BASE6.DAT  is B12E6.DAT
  2797.  
  2798.  
  2799.                                  - 47 -
  2800. ................................................................................
  2801.  
  2802.  
  2803.      Easy Base is a registered trade mark of John Turnbull.
  2804.  
  2805.      Easy Base documentation is copyright John Turnbull 1994. It may
  2806.      be freely distributed as part of the Shareware program and
  2807.      users of Easy Base may print a single copy of the documentation
  2808.      for their own use. All other rights are reserved.
  2809.  
  2810.      Trade marks of any other company included in the documentation
  2811.      are acknowledged.
  2812.  
  2813.      John Turnbull disclaims all warranties as to this software,
  2814.      whether express or implied, including without limitation any
  2815.      implied warranties of merchantability, fitness for a particular
  2816.      purpose, functionality, data integrity or protection.
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.  
  2840.  
  2841.  
  2842.  
  2843.  
  2844.  
  2845.  
  2846.  
  2847.  
  2848.  
  2849.  
  2850.  
  2851.  
  2852.  
  2853.  
  2854.  
  2855.  
  2856.  
  2857.                                  - 48 -
  2858. ................................................................................
  2859.  
  2860.  
  2861.       ════════════════════════════════════════════════════════════════
  2862.                      SELECTED PROGRAMMING TOPICS
  2863.       ────────────────────────────────────────────────────────────────
  2864.  
  2865.                   Address Labels                50
  2866.                   Automatic Lookups             52
  2867.                   Batch Starting                53
  2868.                   Check Off Fields              54
  2869.                   Compound Index                55
  2870.                   Compound Lookups              58
  2871.                   Conditional Lookups           59
  2872.                   Correcting Stats.             60
  2873.                   Creating Runtime              61
  2874.                   Customize Help Line           62
  2875.                   Cyclic Procedures             63
  2876.                   Data Type Conversion          64
  2877.                   Duplicate Prevention          65
  2878.                   Form Letters                  66
  2879.                   Global Defaults               68
  2880.                   Input Screen Format           69
  2881.                   Invoicing/Ordering            70
  2882.                   Keyword/Text Search           73
  2883.                   Linking Applications          75
  2884.                   Maximizing Speed              76
  2885.                   Multiple Columns              78
  2886.                   Printing System Val.          79
  2887.                   Q And A Input Screen          80
  2888.                   Runtime Auto Start            81
  2889.                   Set System Values             82
  2890.                   Tabulation                    83
  2891.                   Totals & Sub Totals           84
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.  
  2904.  
  2905.  
  2906.  
  2907.  
  2908.  
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.  
  2915.  
  2916.                                 - 49 -
  2917. ................................................................................
  2918.       ADDRESS LABELS                                    ADDRESS LABELS
  2919.  
  2920.       The following procedure prints two columns of address labels
  2921.       from a "Addr" form.
  2922.  
  2923.       .......................Procedure code................
  2924.  
  2925.       Declare output fields
  2926.          Addr.name : Addr.street : Addr.town : Addr.pcode
  2927.          Lname : Lstreet : Ltown : Lpcode
  2928.       end
  2929.       for Addr
  2930.          if Lname = blank then
  2931.             Lname = Addr.name : Lstreet = Addrstreet
  2932.             Ltown = Addr.town : Lpcode = Addrpcode
  2933.          else
  2934.             print list items
  2935.             Lname = blank : Lstreet = blank
  2936.             Ltown = Blank : Lpcode  = blank
  2937.          end if
  2938.       next
  2939.       if Lname <> blank then print list items
  2940.  
  2941.       ....................Output Format........................
  2942.  
  2943.       .List Items
  2944.  
  2945.            {Lname field        }       {Addr.name field    }
  2946.            {Lstreet field      }       {Addr.street field  }
  2947.            {Ltown field        }       {Addr.town field    }
  2948.            {Lpcode field       }       {Addr.pcode field   }
  2949.  
  2950.       .end
  2951.  
  2952.  
  2953.       The field positioning and the distance between the .List Items
  2954.       and .end can be adjusted to fit the label paper.
  2955.  
  2956.  
  2957.       If your label paper has three columns then you could use the
  2958.       following procedure.
  2959.  
  2960.       declare output fields
  2961.          Addr.name : Addr.street : Addr.town : Addr.pcode
  2962.          Mname : Mstreet : Mtown : Mpcode
  2963.          Lname : Lstreet : Ltown : Lpcode
  2964.       end
  2965.       declare variables
  2966.          x as number
  2967.       end
  2968.  
  2969.       Continued.
  2970.  
  2971.  
  2972.  
  2973.                                 - 50 -
  2974. ................................................................................
  2975.       ADDRESS LABELS                                    ADDRESS LABELS
  2976.  
  2977.       for addr
  2978.          x = x + 1
  2979.          if Mod(x,3) = 1 then
  2980.             Lname = Addr.name : Lstreet = Addr.street
  2981.             Ltown = Addr.town : Lpcode = Addr.pcode
  2982.          end if
  2983.          if Mod(x,3) = 2 then
  2984.             Mname = Addr.name : Mstreet = Addr.street
  2985.             Mtown = Addr.town : Mpcode = Addr.pcode
  2986.          end if
  2987.          if Mod(x,3) = 0 then
  2988.             Print list items
  2989.             Lname = Blank : Lstreet = blank
  2990.             Ltown = blank : Lpcode = Blank
  2991.             Mname = Blank : Mstreet = blank
  2992.             Mtown = blank : Mpcode = Blank
  2993.          end if
  2994.       next
  2995.       If Lname <> blank then print list items
  2996.  
  2997.  
  2998.       .........................output format...................
  2999.  
  3000.  
  3001.       .list items
  3002.  
  3003.          { Lname       }    { Mname       }   { Addr.name   }
  3004.          { Lstreet     }    { Mstreet     }   { Addr.street }
  3005.          { Ltown       }    { Mtown       }   { Addr.town   }
  3006.          { Lpcode      }    { Mpcode      }   { Addr.pcode  }
  3007.  
  3008.       .end
  3009.  
  3010.  
  3011.  
  3012.       See Also:- Form Letters
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.                                 - 51 -
  3031. ................................................................................
  3032.       Automatic Lookups                              Automatic Lookups
  3033.  
  3034.       Normally, when a user initiates a primary lookup in a text
  3035.       field he will enter a few characters followed by the * in order
  3036.       to narrow down his choice list. If, however, the possible list
  3037.       is fairly small you may wish to have it displayed automatically
  3038.       as if it was the list for a choice field.
  3039.  
  3040.       For example, you have a departments form with a field "name"
  3041.       and there are only twelve records.
  3042.  
  3043.       When entering records to your "Employees" form which has a
  3044.       field for his department, you wish to lookup the department
  3045.       name. If you derive the Department field on this form as
  3046.       "Lookup (Departments,name) and allow user access to it then the
  3047.       user must type at least an * and press return to bring up the
  3048.       list of department names.
  3049.  
  3050.       You can make this list pop up automatically by setting user
  3051.       entry to the department field to "no" and deriving it with the
  3052.       formula:
  3053.  
  3054.       If(Department = Blank,"*",Lookup(Departments,Name))
  3055.  
  3056.       In other words the derivation formula automates the typing of
  3057.       the *.
  3058.  
  3059.       Please note that all forms and input screens must have at least
  3060.       one field to which the user has access. If you wish to make an
  3061.       automatic lookup on a procedure input screen that only has one
  3062.       field then you must add a second field purely to hold the
  3063.       cursor. This can of course be invisible.
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.  
  3076.  
  3077.  
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.                                 - 52 -
  3088. ................................................................................
  3089.       BATCH STARTING                                    BATCH STARTING
  3090.  
  3091.       You can by pass any or all of the sign on parameters either by
  3092.       setting them in the environment or by supplying them on the
  3093.       command line.
  3094.  
  3095.       To log on as terminal one in the sub directory accounts using
  3096.       the password "Fred", add the following lines to your
  3097.       autoexec.bat file:-
  3098.  
  3099.       SET EBT=1
  3100.       SET EBD=ACCOUNTS
  3101.       SET EBP=FRED
  3102.  
  3103.       Or start Easy Base with the command line :-
  3104.  
  3105.       EB T=1 D=ACCOUNTS P=FRED
  3106.  
  3107.       The terminal number parameter applies to network versions only.
  3108.  
  3109.       Any parameters which are not supplied either in the environment
  3110.       or on the command line will be asked for on start up.
  3111.  
  3112.       If you have set the start up parameters in the environment and
  3113.       you start Easy Base with different parameters on the command
  3114.       line, The parameters on the command line override those in the
  3115.       environment.
  3116.  
  3117.       If your application has different passwords for different menu
  3118.       structures you can set the terminal number and directory and
  3119.       leave the user to supply the password.
  3120.  
  3121.       If the user has access to different directories then just set
  3122.       the terminal number and the user can choose the directory and
  3123.       enter the password.
  3124.  
  3125.       See also Runtime Autostart
  3126.  
  3127.  
  3128.  
  3129.  
  3130.  
  3131.  
  3132.  
  3133.  
  3134.  
  3135.  
  3136.  
  3137.  
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.                                 - 53 -
  3145. ................................................................................
  3146.       Check off fields                                Check off fields
  3147.  
  3148.       Occasionally you may wish to have a field which is simply used
  3149.       to mark or "Check off" items to be done or printed. There is no
  3150.       graphical output from Easy Base but you can create a reasonable
  3151.       check off field by making it a choice field and using the two
  3152.       choices ASCII 255 and ASCII 251.
  3153.  
  3154.       You must use ASCII 255 as the blank as a "Blank" choice is
  3155.       deleted at run time and ASCII 251 (√) which is actually the
  3156.       square root sign makes a reasonable "Tick".
  3157.  
  3158.       To enter the characters, hold down the Alt key and type the
  3159.       number on the numeric key pad.
  3160.  
  3161.       To have a form or input screen display with the items ready
  3162.       ticked, just define the tick fields with this choice list,
  3163.       derive them as Default(√) and make the color Text, Alt1 or
  3164.       Alt2. Easy Base will automatically display the help line "Press
  3165.       the space bar to change".
  3166.  
  3167.  
  3168.  
  3169.  
  3170.  
  3171.  
  3172.  
  3173.  
  3174.  
  3175.  
  3176.  
  3177.  
  3178.  
  3179.  
  3180.  
  3181.  
  3182.  
  3183.  
  3184.  
  3185.  
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.                                 - 54 -
  3202. ................................................................................
  3203.       COMPOUND INDEX                                    COMPOUND INDEX
  3204.  
  3205.       If you need to list records from a form in such a way that they
  3206.       are grouped by one field but with each record in the group
  3207.       ordered by another then you can either use a compound index
  3208.       field or "Subindex" the group during the procedure.
  3209.  
  3210.       A compound index field is simply an additional field in which
  3211.       the contents of two or more fields are compounded using the
  3212.       "Jointext" function. The field is indexed and the index on that
  3213.       field can then be used to select records with the desired group
  3214.       ordering.
  3215.  
  3216.       For example:- A "Videos" form has fields for "Title",
  3217.       "RentalPrice" and "Category".
  3218.  
  3219.       To list the records grouped by "Category" but with the "Titles"
  3220.       in each category in alphabetic order you add another field to
  3221.       the form which is Text, Indexed and long enough to hold the
  3222.       contents of both the "category" and "Title" fields. The field
  3223.       is derived by joining the text of the "Category" and "Title"
  3224.       fields.
  3225.  
  3226.       There are a couple of minor complications in creating compound
  3227.       index fields. Firstly the "Jointext" function by default strips
  3228.       any trailing space characters from the text it is joining. If a
  3229.       straight "Jointext" function was used and the first two videos
  3230.       entered were "A Bridge Too Far" and "Snow White" then the
  3231.       compound fields would derive as:-
  3232.  
  3233.       "WarA Bridge Too Far"  and
  3234.       "CartoonSnow White"
  3235.  
  3236.       When what you need is:-
  3237.  
  3238.       "War      A Bridge Too Far"  and
  3239.       "Cartoon  Snow White      "
  3240.  
  3241.       To produce the desired spacing in the compound field use the
  3242.       "Spacepad" function.
  3243.  
  3244.       If the length of the "Category" field is 15 then derive the
  3245.       compound field with - Jointext(spacepad(category,15),title)
  3246.  
  3247.       If you are compounding more than two fields then "spacepad" all
  3248.       the fields being joined to their own field's length except the
  3249.       last one.
  3250.  
  3251.       The maximum length of a text field in Easy Base is 80
  3252.       characters. If the fields you need to compound total more than
  3253.       80 then you must reduce the length of the field names. Compound
  3254.       indices in Text Block fields should not be used.
  3255.  
  3256.  
  3257.  
  3258.                                 - 55 -
  3259. ................................................................................
  3260.       COMPOUND INDEX                                    COMPOUND INDEX
  3261.  
  3262.       Once you have created a compound field and checked that it
  3263.       derives correctly it is normal to define it as invisible and no
  3264.       entry anyway as it is not its contents that are of interest but
  3265.       the order which its index produces.
  3266.  
  3267.       Ex.   Assuming the compound field was called "catgroup"
  3268.  
  3269.       ..........................code..................
  3270.       for videos with catgroup in order
  3271.          print list items
  3272.       next
  3273.       ........................format.................
  3274.       .List Items
  3275.             {Videos.Category Field}     {Videos.Title Field}
  3276.       .End
  3277.  
  3278.  
  3279.       Ex.
  3280.  
  3281.  
  3282.       ...........................code....................
  3283.       declare variables
  3284.          catcheck as text
  3285.       end
  3286.       for videos with catgroup in order
  3287.          if catcheck <> videos,category then print group header
  3288.          catcheck = videos.category
  3289.          print list items
  3290.       next
  3291.       ..........................format...............
  3292.       .Group Header
  3293.          -------------------------------------
  3294.          Films categorized as {category field}
  3295.          -------------------------------------
  3296.       .List Items
  3297.                     {Title field}
  3298.       .End
  3299.  
  3300.       There is yet a further complication if one or more of the
  3301.       fields to be compounded is numeric. Easy Base index files are
  3302.       sorted alphabetically if the field is text and numerically if
  3303.       the field is numeric. A compound field is always text so if you
  3304.       need to compound a numeric field you have to ensure that it
  3305.       will sort alphabetically to the same order that it sorts
  3306.       numerically. The text of numeric values sort alphabetically to
  3307.       the same order as their values only if they all have the same
  3308.       number of digits either side of the decimal point.
  3309.  
  3310.       6  12 and 34 sort alphabetically as 12  34  6
  3311.       but
  3312.       06 12 and 34 sort alphabetically as 06  12  34
  3313.  
  3314.  
  3315.                                 - 56 -
  3316. ................................................................................
  3317.       COMPOUND INDEX                                    COMPOUND INDEX
  3318.  
  3319.       Easy Base provides the function "Zeropad" to pad numbers to the
  3320.       same length for compounding.  The "Zeropad" function has three
  3321.       parameters - The number to be padded, the number of digits left
  3322.       of the decimal to pad to and the number of digits right of the
  3323.       decimal to pad to. All three parameters must be supplied. If
  3324.       the number is an integer then the third parameter is 0.
  3325.  
  3326.       Ex. To list the "Videos" records grouped by rental price with
  3327.       the titles in each price group in order you would create a
  3328.       compound field derived with:-
  3329.  
  3330.       Jointext(zeropad(rentalprice,2,2),title)
  3331.  
  3332.       Ex.
  3333.  
  3334.       A "Ships" form has fields for "Type" and "Displacement"
  3335.  
  3336.       To list the ships grouped by type with the Displacement in each
  3337.       group in order you would create a compound field derived with:-
  3338.  
  3339.       jointext(spacepad(type,15),zeropad(displacement,8,0))
  3340.  
  3341.       In many cases where you wish to compound a mixture of text and
  3342.       numeric fields you will require the numeric values to be listed
  3343.       in descending order while the text value is to be in alphabetic
  3344.       order.
  3345.  
  3346.       In the above example for ships, had you wished each group to
  3347.       be listed with "Displacement" in descending order you would
  3348.       derive the compound field as:-
  3349.  
  3350.       jointext(spacepad(type,15),reverse(zeropad(displacement,8,0)))
  3351.  
  3352.       The "Reverse" function simply inverts the ACSII number of each
  3353.       character in its parameter so that it will sort in reverse
  3354.       order in the index file.
  3355.  
  3356.       The "Reverse" function works equally well on text values
  3357.       although reverse alphabetic lists are seldom required.
  3358.  
  3359.       The "Zeropad" function will only pad out a number to the size
  3360.       required. It will not trim the number if it is already longer
  3361.       than one of the pad lengths. You should not therefore create
  3362.       compound fields with Floating Point numbers.
  3363.  
  3364.       If you compound a date or time field you should zeropad it to
  3365.       5,0 as the text which will be used is actually the date or time
  3366.       fields numeric value.
  3367.  
  3368.  
  3369.  
  3370.  
  3371.  
  3372.                                 - 57 -
  3373. ................................................................................
  3374.       COMPOUND LOOKUPS                                COMPOUND LOOKUPS
  3375.  
  3376.       Occasionally, in an input screen, you will wish to lookup
  3377.       details from a form whose unique field is a compound of two
  3378.       others.  As an example, if you wished to lookup details from
  3379.       the "Userlist" form, mentioned in the manual, then you would
  3380.       have to base the lookups on a relationship between a field on
  3381.       the input screen and the "UNI" field in "Userlist". The "UNI"
  3382.       field in userlist is a combination of the "Aircraft" forms
  3383.       "Knownas" field and the "Airlines" form "Name" field.
  3384.  
  3385.       Although you could simply use a field "UNI" on the input screen
  3386.       and derive it :- Lookup(userlist,uni) - this would mean that
  3387.       the end user would have to enter the whole of the aircraft
  3388.       Knownas part plus part of the airlines name part plus the "*"
  3389.       in order to get the lookup.
  3390.  
  3391.       This would not only be awkward to use but would also entail
  3392.       explaining compound fields to the end user.
  3393.  
  3394.       You can avoid this situation by providing two fields, one in
  3395.       which the user looks up the aircraft knownas field and one in
  3396.       which he looks up the airline name. These are based on separate
  3397.       relationships between the input screen and the "Aircraft" and
  3398.       "Airlines" forms.
  3399.  
  3400.       The input screen's "UNI" field can now be made invisible with
  3401.       no user entry and derived:- Jointext(knownas,name).
  3402.  
  3403.       A relationship is entered between the input screen and the
  3404.       "Userlist" form linking the "UNI" fields and all the required
  3405.       details can then be derived :- lookup(userlist,whatever).
  3406.  
  3407.  
  3408.  
  3409.  
  3410.  
  3411.  
  3412.  
  3413.  
  3414.  
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.  
  3428.  
  3429.                                 - 58 -
  3430. ................................................................................
  3431.       Conditional Lookups                          Conditional Lookups
  3432.  
  3433.       Occasionally you may wish to use a single field either to
  3434.       initiate a lookup or to accept direct input from the keyboard.
  3435.  
  3436.       For example on an input screen to a procedure that enters
  3437.       invoice lineitems there is a field Partname which is related to
  3438.       the Name field in the "Parts" form. The entry to this field
  3439.       initiates a primary lookup for its own value and a secondary
  3440.       for the Price field. The user enters the first few characters
  3441.       of the part name followed by an *, then chooses the part name
  3442.       from the lookup list. If you also wish the user to be able to
  3443.       enter a partname that is not in the parts form then derive the
  3444.       partname field:-
  3445.  
  3446.       If(Intext(Partname,"*") > 0,Lookup(Parts,Name),Partname)
  3447.  
  3448.       If the user enters an * anywhere in the field then a lookup
  3449.       will be done from the parts form, but if he does not enter an *
  3450.       then the field will retain whatever name he entered.
  3451.  
  3452.       If you wish to be able to tell whether or not a lookup has been
  3453.       made for use in the procedure code - perhaps to add the new
  3454.       part to the parts form - then use a special character other
  3455.       than the * as the condition.
  3456.  
  3457.       For example, if you derive Partname as:-
  3458.  
  3459.       If(Lefttext(Partname,1) = "+",Partname,Lookup(Parts,Name))
  3460.  
  3461.       then any entry to the field which starts with the "+" character
  3462.       will not initiate the lookup. You can then use the fact that
  3463.       the partname starts with a + to enter a new record in the parts
  3464.       form.
  3465.  
  3466.       Declare variables
  3467.          NN as text
  3468.       end
  3469.       NN = Input.partname
  3470.       If Lefttext(NN,1) = "+" then
  3471.          NN = righttext(NN,Lengthtext(NN)-1)
  3472.          For parts new record
  3473.             Parts.name = NN
  3474.          Next
  3475.       End if
  3476.       for Invoicelines
  3477.          copy all from input
  3478.          Partname = NN
  3479.       next
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.                                 - 59 -
  3487. ................................................................................
  3488.       CORRECTING STATS.                              CORRECTING STATS.
  3489.  
  3490.       If you write an application in which records are entered via
  3491.       procedures and "running" statistics are kept, you will have to
  3492.       provide procedures which allow the user to correct any mistakes
  3493.       he has made.
  3494.  
  3495.       For Example: - In a "Time Sheets" application the user enters a
  3496.       time and customer on the input screen of a procedure. The
  3497.       procedure then calculates the charge, writes the charge and
  3498.       customers name to the "Timesheet" form, adds the charge to the
  3499.       "Balance" field in the "Customers" form and also adds it to the
  3500.       "Total" field in the "Workinhand" form.
  3501.  
  3502.       If the operator makes an error then correcting the entry in the
  3503.       "Timesheet" form is simply a case of updating it but to correct
  3504.       the "Balance" and "Total" fields you must add the corrected
  3505.       value and subtract the old incorrect value.
  3506.  
  3507.       To get the two values together for your procedure, create an
  3508.       input screen where the operator enters the "line" ("line" is
  3509.       the unique sequenced field in "Timesheet").  Then create two
  3510.       fields for the values. The first, "oldval" is derived
  3511.       lookup(timesheet,charge) and the second, "newval" is derived
  3512.       default(lookup(timesheet,charge).
  3513.  
  3514.       The "Oldval" field can be invisible and has no user entry.
  3515.  
  3516.       You would also add two similarly derived fields "Oldcustomer"
  3517.       and "Newcustomer".
  3518.  
  3519.       When the user edits the "Newval" and/or "Newcustomer" field and
  3520.       presses F2 , all the required values are available to the
  3521.       procedure code:-
  3522.  
  3523.       pause off : escape off
  3524.       for timesheet with line = input.line
  3525.          timesheet.charge = input.newval
  3526.          timesheet.customer = input.newcustomer
  3527.          update record
  3528.       next
  3529.       for customers with name = input.oldcustomer
  3530.          customers.balance = customers.balance - input.oldval
  3531.          update record
  3532.       next
  3533.       for customers with name = input.newcustomer
  3534.          customers.balance = customers.balance + input.newval
  3535.          update record
  3536.       next
  3537.       for workinhand
  3538.         workinhand.total = workinhand.total+input.newval-input.oldval
  3539.         update record
  3540.       next
  3541.  
  3542.  
  3543.                                 - 60 -
  3544. ................................................................................
  3545.       CREATING RUNTIME                                CREATING RUNTIME
  3546.  
  3547.       To create a distributable application with the Easy Base
  3548.       Royalty free Runtime Module, first, ensure that your
  3549.       application has a user menu with a start up password. If you
  3550.       wish your runtime application to start without a sign on screen
  3551.       then this password should be "Autostart".
  3552.  
  3553.       Make a new directory for your module and copy all the files
  3554.       from the Easy Base sub directory in which you developed the
  3555.       application to it.
  3556.  
  3557.       Copy the Configuration file "EB.SET" from your Easy Base
  3558.       directory to this directory.
  3559.  
  3560.       Insert the Runtime Module disk in a floppy drive. Change to
  3561.       that drive and type "MODULE".
  3562.  
  3563.       The "Module" program will first ask you for the path to the
  3564.       application files. Once you enter this it will unpack the
  3565.       runtime files into your new directory.
  3566.  
  3567.       It will then ask for the name of your application. The name you
  3568.       supply here will be displayed on any sign on screens and also
  3569.       on the shutdown "Thank you for using - " line.
  3570.  
  3571.       It will then ask you for your copyright line. The text you
  3572.       enter here will replace the line "Application of Easy Base -
  3573.       Not for Resale" which appears above your menus.
  3574.  
  3575.       Finally, you will be asked for the Executable file name you
  3576.       wish to use for your program.
  3577.  
  3578.       When you have entered the details - Press F2 and your
  3579.       application will be complete and ready to sell.
  3580.  
  3581.                       --------------------------
  3582.  
  3583.       EASY INSTALL UTILITY
  3584.  
  3585.       For professional distribution disks just like the ones Easy
  3586.       Software is distributed on, you can purchase Easy Install.
  3587.       This utility will compress your application and create a
  3588.       distribution disk with an install program customized for your
  3589.       application.
  3590.  
  3591.  
  3592.  
  3593.  
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.                                 - 61 -
  3601. ................................................................................
  3602.       CUSTOMIZE HELP LINE                          CUSTOMIZE HELP LINE
  3603.  
  3604.       You can replace the default help line (bottom line) in both
  3605.       data entry and procedure input screens.
  3606.  
  3607.       Press F6 in form or input screen design to access the help
  3608.       line.
  3609.  
  3610.       If you wish to revert to the default help line just erase your
  3611.       customized one.
  3612.  
  3613.       The line which you enter here becomes the default but is
  3614.       overridden when the cursor is in any field with a Help prefix.
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.  
  3634.  
  3635.  
  3636.  
  3637.  
  3638.  
  3639.  
  3640.  
  3641.  
  3642.  
  3643.  
  3644.  
  3645.  
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.                                 - 62 -
  3658. ................................................................................
  3659.       CYCLIC PROCEDURES                              CYCLIC PROCEDURES
  3660.  
  3661.       In many applications you will come across the situation where
  3662.       you need a procedure which will perform the same actions on a
  3663.       given set of records. For example, in a payroll system the
  3664.       procedure which calculates the employees wage and deductions
  3665.       has to be repeated for each employee so that their hours can be
  3666.       entered. If you simply enter each employees Worksno and lookup
  3667.       his or her details then it will be easy to miss an employee or
  3668.       to do one twice.
  3669.  
  3670.       To avoid this you can create a procedure which will cycle each
  3671.       employee through the input screen and terminate when all
  3672.       employees have been processed.
  3673.  
  3674.       On the employees form, add a field "Cycled" which is a single
  3675.       character indexed field derived :- Default("N").
  3676.  
  3677.       On the procedure input screen add an invisible field "Cycled"
  3678.       which is derived "N"
  3679.  
  3680.       You now enter two relationships between the procedure and the
  3681.       employees form. The main relationship "Employees" links the
  3682.       fields "Worksno" and the second, lets call it "Cycled" links
  3683.       the "Cycled" fields.
  3684.  
  3685.       On the input screen you derive the "Worksno" field as
  3686.       Lookup(cycled,worksno) and all the other details as
  3687.       lookup(employees,Whatever).
  3688.  
  3689.       When you run the procedure, the first employees details will be
  3690.       loaded automatically and all you have to enter are his hours.
  3691.  
  3692.       To have the next employee loaded after you run the procedure,
  3693.       the procedure code simply includes the lines:-
  3694.  
  3695.       for employees with worksno = input.worksno
  3696.          employees.cycled = "Y"
  3697.          update record
  3698.       next
  3699.  
  3700.       When all employees have been processed the "Worksno" field will
  3701.       derive blank as there are no employees with "N" in the "Cycled"
  3702.       field. You can therefore pass a "finished" message by altering
  3703.       the derivation of "Worksno" to :-
  3704.  
  3705.         if(lookup(cycled,worksno)=blank,blank[beepAll Employees have
  3706.         now been processed],lookup(cycled,worksno))
  3707.  
  3708.       To reset cycling for the next payroll you write an additional
  3709.       procedure with the code:-
  3710.       for employees
  3711.          employees.cycled = "N" : update record
  3712.       next
  3713.  
  3714.                                 - 63 -
  3715. ................................................................................
  3716.       Data Type Conversion                        Data Type Conversion
  3717.  
  3718.       In Easy Base, modifying the structure of a data file after it
  3719.       contains data is very easy and flexible. If you select Modify
  3720.       Existing Form from the Forms menu you can add fields, delete
  3721.       fields, change field order, change field lengths and Easy Base
  3722.       will reformat your existing data automatically.
  3723.  
  3724.       You can NOT however change data types simply by changing the
  3725.       field type. If you change a field type and save the form you
  3726.       will almost certainly lose the data that was in that field.
  3727.       (Other than changing from one numeric type to another)
  3728.  
  3729.       If you work entirely within Easy Base there is no reason why
  3730.       you should ever need to change a field type. However, if you
  3731.       have imported data from Dbase or Fixed Length ASCII you may
  3732.       find yourself with numeric or date values held in text fields.
  3733.  
  3734.       The procedure for converting data from one type to another is
  3735.       as follows:-
  3736.  
  3737.       1.   Select Modify Existing Form
  3738.  
  3739.       2.   Add a new field of the desired type with a derivation
  3740.            formula such that it will derive its value from the field
  3741.            of the old type.
  3742.  
  3743.       3.   Save the form.
  3744.  
  3745.       4.   Select Modify the form again.
  3746.  
  3747.       5.   Cancel the derivation formula in the new field and delete
  3748.            the old field.
  3749.  
  3750.       6.   Re save the form.
  3751.  
  3752.  
  3753.       To derive a numeric field from a text field the derivation
  3754.       formula is simply the text field name.
  3755.  
  3756.       To derive a date field from a Dbase imported date in a text
  3757.       field called DT the formula is:-
  3758.  
  3759.       Makedate(midtext(DT,5,2),midtext(DT,7,2),midtext(DT,3,2))
  3760.  
  3761.       Version 3.10
  3762.  
  3763.       From V3.1 you can change field types between text and numeric
  3764.       and retain any numeric values that were in the field
  3765.       automatically . You still cannot change a field type from date
  3766.       or time to text or vice versa without following the above
  3767.       procedure.
  3768.  
  3769.  
  3770.  
  3771.                                 - 64 -
  3772. ................................................................................
  3773.       DUPLICATE PREVENTION                        DUPLICATE PREVENTION
  3774.  
  3775.       1.  Where "Blank" values are acceptable.
  3776.  
  3777.       Quite often you will come across a situation where a field must
  3778.       not have duplicate entries but can still be left blank. You
  3779.       cannot define this field as unique because that would prevent
  3780.       more than one blank entry.  A good example of such a situation
  3781.       is in the "Menus Form" of Easy Base. The definition and unique
  3782.       field is the "Menu Title" but no two records may have the same
  3783.       entry in the sign on "Password" field.
  3784.  
  3785.       To prevent duplicate entries other than blanks you must enter a
  3786.       relationship between the form and itself with the field to be
  3787.       tested as the related field in both primary and secondary
  3788.       forms.
  3789.  
  3790.       The field is then derived as :-
  3791.  
  3792.       If(lookup(menus,password) <> blank,blank[beepDuplicate Password
  3793.                !],password)
  3794.  
  3795.       2.   When entering records via procedures.
  3796.  
  3797.       When you use a procedure to enter a new record to a form it is
  3798.       not automatically checked as "Unique".   To ensure that
  3799.       duplicate entries are not entered via procedures you must check
  3800.       that the data entered on the procedures input screen is unique
  3801.       to the form you are about to enter it to before running the
  3802.       procedure.  For example: If you were about to enter a record to
  3803.       the "Manufacturers" form in which the "Name" field was unique
  3804.       then the "Name" field on the input screen would be derived:-
  3805.  
  3806.          if(lookup(manufacturers,name) <> blank,blank[beepDuplicate
  3807.                     Name !cursor name],name)
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.                                 - 65 -
  3829. ................................................................................
  3830.       FORM LETTERS                                        FORM LETTERS
  3831.  
  3832.       To print form letters (circulars) with a different address and
  3833.       salutation for each entry in an address form simply type the
  3834.       entire letter between the .List Items and .End of the output
  3835.       format.
  3836.  
  3837.       .........................procedure code........
  3838.       Declare output fields
  3839.          Addr.name : Addr.street : Addr.town
  3840.          Addr.salutation
  3841.          date
  3842.       end
  3843.       date = datetext(system date)
  3844.       for addr
  3845.          print list items
  3846.          page feed
  3847.       next
  3848.  
  3849.       .........................output format........
  3850.       .List Items
  3851.                                              My street
  3852.                                              My county
  3853.                                              {date field  }
  3854.  
  3855.  
  3856.       {Addr.name field    }
  3857.       {Addr.street field  }
  3858.       {Addr.town field    }
  3859.  
  3860.  
  3861.       Dear {Addr.salutation},
  3862.  
  3863.           You are invited................................
  3864.       ...................................................
  3865.       ...................................................
  3866.       ..........................................
  3867.  
  3868.       Yours faithfully,
  3869.  
  3870.  
  3871.  
  3872.       Fred A Blogs
  3873.       .End
  3874.  
  3875.       Although this is the fastest way to produce a short form
  3876.       letter, the Format Editor is not the nicest place to write
  3877.       text. If you want the benefits of word wrap and spell checking
  3878.       then you can create a form in which to write the letter. Create
  3879.       text block fields to hold a page of text and a name field so
  3880.       that you can store many different letters and print them with
  3881.       the same procedure. If your letters are to be more than one
  3882.       page long then put the same name on each page.
  3883.  
  3884.  
  3885.                                 - 66 -
  3886. ................................................................................
  3887.       FORM LETTERS                                        FORM LETTERS
  3888.  
  3889.       To print the form letters from the "Letters" form your
  3890.       procedure must now have an input screen which looks up the name
  3891.       of the letter to be printed.
  3892.  
  3893.       '............................CODE.....................
  3894.       declare output fields
  3895.          addr.name : addr.street : addr.town :addr.salutation
  3896.          date :letters.block1 :letters.block2 :letters.block3
  3897.       end
  3898.       declare variables
  3899.          page as number
  3900.       end
  3901.       date = datetext(system date)
  3902.       for addr
  3903.          page = 0
  3904.          for letters with name = input.name
  3905.             page = page + 1
  3906.             if page = 1 then print list items
  3907.             if page > 1 then print extra
  3908.             page feed
  3909.          next
  3910.       next
  3911.  
  3912.       The output format is similar to that shown on the previous page
  3913.       but the text in the .list items section is replaced by the text
  3914.       block fields Letters.block1 ,letters.block2 and letters.block3
  3915.       and an additional section .extra is added which has the same
  3916.       text block fields but no address or salutation.
  3917.  
  3918.  
  3919.  
  3920.  
  3921.  
  3922.  
  3923.  
  3924.  
  3925.  
  3926.  
  3927.  
  3928.  
  3929.  
  3930.  
  3931.  
  3932.  
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.                                 - 67 -
  3943. ................................................................................
  3944.       GLOBAL DEFAULTS                                  GLOBAL DEFAULTS
  3945.  
  3946.       In many instances, an application will use the same default
  3947.       values in many procedures and field derivations. If you
  3948.       "hardwire" these as constants into your procedures and code
  3949.       then they will all have to be changed when the default value
  3950.       changes.
  3951.  
  3952.       Easy Base is supplied with a single global defaults form for
  3953.       VAT rates but you can create your own for any particular
  3954.       application.
  3955.  
  3956.       For instance, should you write a payroll system you would wish
  3957.       to be able to update the tax rates and bands globally
  3958.       throughout your application when they change.
  3959.  
  3960.       To do this, create a form to hold all the global defaults. In
  3961.       addition to the default fields add a single character text
  3962.       field derived "X" and index it. You then enter a single record
  3963.       with all the default values. The "X" field is there to create
  3964.       an artificial relationship between any input screen and the
  3965.       defaults form in order to lookup defaults.
  3966.  
  3967.       Wherever you need one or more global defaults in an input
  3968.       screen you simply add an invisible "x" field and enter a
  3969.       relationship between the procedure and the defaults form
  3970.       linking the "x" fields.
  3971.  
  3972.       The field "Tax" can now be derived:-
  3973.  
  3974.          taxablepay * lookup(defaults,taxrate)
  3975.  
  3976.       Similarly, you can pre load variables in procedure code for the
  3977.       default values:-
  3978.  
  3979.       Declare variables
  3980.         Taxrate1 as number:Taxrate2 as number
  3981.         Taxband1 as number:Taxband2 as number
  3982.       end
  3983.       for defaults
  3984.         Taxrate1 = defaults.taxrate1 :Taxrate2 = defaults.taxrate2
  3985.         Taxband1 = defaults.taxband1 :Taxband2 = defaults.taxband2
  3986.       next
  3987.  
  3988.       When the taxrates change you only have to alter them once in
  3989.       the Defaults form.
  3990.  
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.                                 - 68 -
  4000. ................................................................................
  4001.       Input Screen Format                          Input Screen Format
  4002.  
  4003.       All form and input screens can be presented either mounted in a
  4004.       window against a mottled background or exactly as drawn in form
  4005.       design. The windowing effect is done automatically if you leave
  4006.       a clear border around all text and fields. If you place fields
  4007.       or text anywhere against the edge of the screen (even invisible
  4008.       fields) then the window effect will not be invoked.
  4009.  
  4010.       If you do not want the window effect but you still wish to
  4011.       leave a clear border then you should place the invisible text
  4012.       character (ASCII 255) in the top left hand corner of the
  4013.       screen to disable it. To produce the invisible character hold
  4014.       down the Alt Key and type 255 on the numeric keypad.
  4015.  
  4016.  
  4017.  
  4018.  
  4019.  
  4020.  
  4021.  
  4022.  
  4023.  
  4024.  
  4025.  
  4026.  
  4027.  
  4028.  
  4029.  
  4030.  
  4031.  
  4032.  
  4033.  
  4034.  
  4035.  
  4036.  
  4037.  
  4038.  
  4039.  
  4040.  
  4041.  
  4042.  
  4043.  
  4044.  
  4045.  
  4046.  
  4047.  
  4048.  
  4049.  
  4050.  
  4051.  
  4052.  
  4053.  
  4054.  
  4055.  
  4056.                                 - 69 -
  4057. ................................................................................
  4058.       Invoicing/Ordering                            Invoicing/Ordering
  4059.  
  4060.       To create a simple order processing or invoicing system you
  4061.       need forms for :
  4062.  
  4063.          Stock     (ID#,descrip,price,qtyonhand etc)
  4064.          Customers (ID#,name,address etc)
  4065.          Lineitems (Customer ID,Item ID,Qty,price)
  4066.          Last      (Single record with Last invoice/order number)
  4067.          Current   (Single record for current Cust ID/Invoice No)
  4068.  
  4069.       Both of the forms "Last" and "Current" also have a field called
  4070.       "X" which is a single character indexed text field containing
  4071.       the character "x"
  4072.  
  4073.       You also need three procedures:
  4074.  
  4075.          SelectCustomer
  4076.          EnterItems
  4077.          PrintInvoice
  4078.  
  4079.       The first procedure has an input screen on which you verify the
  4080.       Customers ID# for the invoice. Whether you do this by entering
  4081.       the ID# and looking up the name and address to verify it or by
  4082.       using a primary lookup on the customers name is up to you.
  4083.  
  4084.       The input screen also has an invisible single character text
  4085.       field which is derived "X" and an InvoiceNo field. As well as
  4086.       the relationship to lookup the customers name, the input screen
  4087.       is also related to the Last form linking the "X" fields.
  4088.  
  4089.       The InvoiceNo field is derived Lookup(Last,InvoiceNo) + 1
  4090.  
  4091.       When you have looked up the Customer you run this procedure
  4092.       which has the code:
  4093.       ...................................................
  4094.       For Last
  4095.          Last.Invoiceno = Input.Invoiceno : Update Record
  4096.       Next
  4097.       For Current
  4098.          Current.Invoiceno = Input.Invoiceno
  4099.          Current.CustomerID = Input.CustomerID
  4100.          Update Record
  4101.       Next
  4102.       Run EnterItems
  4103.       ..............................................
  4104.       The second procedure "Enteritems" now takes over and it has an
  4105.       input screen where you lookup items from your stock form
  4106.       together with their price, and enter the quantity. This
  4107.       procedure has a repeating input screen. It is used to enter one
  4108.       line at a time into the LineItems form. You must also nominate
  4109.       a function key which will be used to run the PrintInvoice
  4110.       procedure when all invoice items have been entered. A suitable
  4111.       default help line might be:-
  4112.  
  4113.                                 - 70 -
  4114. ................................................................................
  4115.       Invoicing/Ordering                            Invoicing/Ordering
  4116.  
  4117.       "F2=Enter Invoice Item   F4=Print Invoice  F10=Cancel"
  4118.  
  4119.       It is important that the user should not terminate this
  4120.       procedure with the escape key so you should disable it and the
  4121.       other function keys in one of your field derivations:
  4122.  
  4123.       Disable "Esc5789"
  4124.  
  4125.       Like the SelectCustomer procedure this screen also has an
  4126.       invisible "x" field - no entry and derived "X". This time it is
  4127.       related to the X field in the Current form. There are fields
  4128.       for InvoiceNo and CustomerID. Both are no entry and are
  4129.       derived: Lookup(Current,InvoiceNo)  Lookup(Current,CustomerID)
  4130.  
  4131.       The main relationship of course is to the Stock form to lookup
  4132.       the stock item and price. Again, like the first procedure, it
  4133.       is up to you whether you enter stock ID#s and lookup the
  4134.       description and price or do a primary lookup on the Stock
  4135.       Descrip field. This procedure writes a new record to the
  4136.       LineItems form if F2 is pressed, runs Printinvoice if F4 is
  4137.       pressed and "Tidies Up" if F10 is pressed.
  4138.       ................................................
  4139.       If Fun_Key = 4 then run Printinvoice
  4140.       If Fun_Key = 10 then
  4141.          for LineItems with InvoiceNo = Input.InvoiceNo
  4142.             Delete Record
  4143.          Next
  4144.          For Last
  4145.             Last.Invoiceno = Last.Invoiceno - 1 : Update record
  4146.          Next
  4147.          Run SelectCustomer
  4148.       End if
  4149.       For LineItems new record
  4150.          Copy all from Input
  4151.       Next
  4152.       ..............................................
  4153.       The third procedure "PrintInvoice" is run when the user presses
  4154.       F4 and has the Following code.
  4155.  
  4156.       Declare output fields
  4157.          Customers.Name : Customers.Address
  4158.          LineItems.StockID : LineItems.Descrip : LineItems.Qty
  4159.          LineItems.Price
  4160.          LineTotal : SubTotal : Tax : GrandTotal
  4161.          InvoiceNo : CustomerID
  4162.       End
  4163.       '............Get Nos from Current
  4164.       For Current
  4165.          InvoiceNo = Current.Invoiceno
  4166.          CustomerID = Current.CustomerID
  4167.       Next
  4168.  
  4169.  
  4170.                                 - 71 -
  4171. ................................................................................
  4172.       Invoicing/Ordering                            Invoicing/Ordering
  4173.  
  4174.       '.......Print Customer details to invoice header
  4175.       For Customers with ID = CustomerID
  4176.          Print Report Header
  4177.       Next
  4178.       '.................Print Invoice Lines...
  4179.       For LineItems with InvoiceNo = InvoiceNo
  4180.          LineTotal = LineItems.Price * LineItems.Qty
  4181.          SubTotal = Subtotal + LineTotal
  4182.          Print List Items
  4183.          '........Update Stock on hand
  4184.          For stock with ID = LineItemsID
  4185.             Stock.Qtyonhand = Stock.Qtyonhand - LineItems.Qty
  4186.             Update Record
  4187.          Next
  4188.       Next
  4189.       ,..................Report Footer
  4190.       Tax = VATon(SubTotal)
  4191.       GrandTotal = Subtotal + Tax
  4192.       Print Report Footer
  4193.       Page Feed
  4194.  
  4195.       Notice that the Quantity on hand field in the stock form is not
  4196.       updated until you actually print the invoice. You could have
  4197.       done it while you were entering the Line Items but it would
  4198.       make the tidying process more complicated if the invoice were
  4199.       cancelled with F10 after items had been written.
  4200.  
  4201.  
  4202.  
  4203.  
  4204.  
  4205.  
  4206.  
  4207.  
  4208.  
  4209.  
  4210.  
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.  
  4224.  
  4225.  
  4226.  
  4227.                                 - 72 -
  4228. ................................................................................
  4229.       Keyword/Text Search                          Keyword/Text Search
  4230.  
  4231.       If you have a database with a large number of items where the
  4232.       user would be unlikely to know exactly what he is looking for
  4233.       you will need to provide a search facility based on text
  4234.       supplied by the user. There are two main ways to do this and
  4235.       both have advantages in different situations.
  4236.  
  4237.       Suppose you have a form for technical publications. There are
  4238.       fields for Name, Publisher, Price, Short Description Etc. A
  4239.       user wishing to search this form will not know the contents of
  4240.       any of the fields - he will only know the topic or subject
  4241.       which he wants to look up.
  4242.  
  4243.       You need to get some search text from the user, find the names
  4244.       of any publications which may cover the subject then make a
  4245.       short list of them in the PickList form.
  4246.  
  4247.       The simplest way is to have an input screen field where the
  4248.       user can enter search text, then search the "ShortDescrip"
  4249.       field for the occurrence of the text he has entered. Wherever
  4250.       his text is found you add a new record to the PickList form.
  4251.       The user can then mark the titles which interest him and you
  4252.       can print out the short descriptions of the publications he has
  4253.       chosen.
  4254.  
  4255.       Clear records from PickList
  4256.       for Publications
  4257.          If intext(shortdescrip,input.searchtext) > 0 then
  4258.             for PickList new record
  4259.                PickList.Item = Publications.Name
  4260.             next
  4261.          end if
  4262.       next
  4263.       Show Picklist
  4264.       For PickList with Mark = Chr$(251)
  4265.          For Publications with Name = Picklist.Item
  4266.             Print List Items
  4267.          next
  4268.       next
  4269.  
  4270.       The advantage of this method is that the user is free to enter
  4271.       any text and will get a "Hit" if it exists anywhere in the
  4272.       description. The disadvantage is that every record in the
  4273.       publications form has to be searched. This form of searching
  4274.       becomes too time consuming if there are many thousands of
  4275.       records. You can overcome the time problem in a large database
  4276.       by adding a KeyWord form.
  4277.  
  4278.       A KeyWord form has two fields, one for the publication name and
  4279.       one for a key word. Each publication can have several entries
  4280.       in this form with different key words. The Keyword field is
  4281.       indexed so if you now search this form for the entered text you
  4282.       will get a list of publications with the entered keyword very
  4283.  
  4284.                                 - 73 -
  4285. ................................................................................
  4286.       Keyword/Text Search                          Keyword/Text Search
  4287.  
  4288.       quickly. The disadvantage of this method is that the user will
  4289.       only get a "Hit" if he enters a word that you have chosen as a
  4290.       KeyWord.
  4291.  
  4292.       You can optimize this method by choosing Keywords that might
  4293.       contain text the user might enter within them. Eg use the
  4294.       keyword "Installation" rather than "Install" and make your
  4295.       routine select with >= rather than =
  4296.  
  4297.       Declare variables
  4298.         Len as number
  4299.       end
  4300.       Len = lengthtext(input.searchtext)
  4301.       For Keywords with Key >= input.searchtext
  4302.          if lefttext(keywords.Key,Len) <> input.searchtext then
  4303.             exit for
  4304.          end if
  4305.          for PickList new Record
  4306.             Picklist.Item = Keywords.Publication
  4307.          next
  4308.       Next
  4309.       Show Picklist
  4310.       For PickList with Mark = Chr$(251)
  4311.          For Publications with Name = PickList.Item
  4312.             Print List Items
  4313.          Next
  4314.       Next
  4315.  
  4316.       Entering Keyword records can be incorporated into the procedure
  4317.       which writes the Publications record to save time when entering
  4318.       data.
  4319.  
  4320.       For Publications new record
  4321.          Copy all from input
  4322.       Next
  4323.       for Keywords new record
  4324.          Keywords.Publication = Input.Name
  4325.          Keywords.Key = Input.Keyword1
  4326.       next
  4327.       If Input.Keyword2 <> blank then
  4328.          For Keywords new record
  4329.             Keywords.Publication = Input.Name
  4330.             Keywords.Key = Input.Keyword2
  4331.          Next
  4332.       End if
  4333.  
  4334.       Repeat last section for the number of keywords on the input
  4335.       screen.
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.                                 - 74 -
  4342. ................................................................................
  4343.       LINKING APPLICATIONS                        LINKING APPLICATIONS
  4344.  
  4345.       Procedures in one directory can access forms in another
  4346.       directory or disk by placing the external forms path in
  4347.       brackets immediately after the form name at the start of a For
  4348.       Loop.
  4349.  
  4350.       Ex.
  4351.  
  4352.       For payroll (c:\pay) with posted = "No"
  4353.          for purchaseledger new record
  4354.             copy all from payroll
  4355.          next
  4356.          payroll.posted = "Yes"
  4357.          update record
  4358.       next
  4359.  
  4360.       The above procedure, in an accounts application, imports data
  4361.       from a payroll application in C:\PAY and updates the "Posted"
  4362.       field in the payroll application.
  4363.  
  4364.       Ex.
  4365.  
  4366.       for sales (A:\) alias import
  4367.          for sales new record
  4368.            copy all from import
  4369.          next
  4370.       next
  4371.  
  4372.       The above procedure is used to import data transferred from one
  4373.       machine to another on floppy disk.
  4374.  
  4375.       Note:-
  4376.  
  4377.       1.   If transferring data on floppy disk the floppy must hold
  4378.       the forms .DAT and .DEF files together with the BASE.DIR from
  4379.       the source application. If you need to move large amounts of
  4380.       data on floppy it is much quicker to simply overwrite an import
  4381.       forms .DAT file and then pack it to rewrite the indices.
  4382.  
  4383.  
  4384.  
  4385.  
  4386.  
  4387.  
  4388.  
  4389.  
  4390.  
  4391.  
  4392.  
  4393.  
  4394.  
  4395.  
  4396.  
  4397.  
  4398.                                 - 75 -
  4399. ................................................................................
  4400.       MAXIMIZING SPEED                                MAXIMIZING SPEED
  4401.  
  4402.       Because the procedures you create in Easy Base have to be
  4403.       interpreted each time they are run they will tend to be slower
  4404.       than similar routines created in a compiled system. This is the
  4405.       unavoidable cost of ease of use. You can increase speed vastly
  4406.       by having the best DOS environment and by the way in which you
  4407.       write procedure code.
  4408.  
  4409.       DOS Environment.
  4410.  
  4411.       1.   Do not use a disk compression system.
  4412.  
  4413.       2.   Always load "Fastopen"  - The default settings are fine -
  4414.            just add the line "fastopen C:" to your AUTOEXEC.BAT file.
  4415.  
  4416.       3.   Use a Disk Cacheing system - The more memory you can
  4417.            allocate to it the better. Easy Software recommends
  4418.            PC-Cache from Centre Point with 2 Megabytes of expanded
  4419.            memory allocated. Smartdrive (Version supplied with
  4420.            Windows 3.1) was slightly faster but caused widespread
  4421.            disk corruptions during test "Power Failures".
  4422.       4.   Do not run any TSR programs (Especially Virus Checkers).
  4423.  
  4424.       Procedure Code.
  4425.  
  4426.       Avoid making calculations and derivations within "For" loops in
  4427.       procedures.
  4428.  
  4429.       If, for example, you had a form in which was recorded the
  4430.       length, breadth and depth of various blocks and you knew that
  4431.       at some point you would write a procedure which listed their
  4432.       volume. Add a field for volume to the form and derive it from
  4433.       the other fields. When you write the procedure you will simply
  4434.       list this field. If the field had not been added to the form
  4435.       then you would have to calculate its value on each iteration of
  4436.       the "For" loop.
  4437.  
  4438.       The time taken to derive each individual "Volume" field during
  4439.       record entry will not be noticeable but the time taken to
  4440.       derive the volume for every record during the procedure will.
  4441.  
  4442.       Keep "Running statistics".  If your program requires statistics
  4443.       derived from many hundreds or even thousands of records then
  4444.       having to wait for a procedure which calculates them each time
  4445.       you want up to date figures is a real pain.
  4446.  
  4447.       To keep "running statistics" create a form with a field for
  4448.       each statistic you require and enter a single record with zero
  4449.       values in each field. Make all entries, modifications and
  4450.       deletions to your data via procedures and you can update your
  4451.       statistics each time a record is added, modified or deleted.
  4452.  
  4453.       Example on next page.
  4454.  
  4455.                                 - 76 -
  4456. ................................................................................
  4457.       MAXIMIZING SPEED                                MAXIMIZING SPEED
  4458.  
  4459.       The following procedure code enters a record (collected via the
  4460.       input screen) to a purchases ledger and updates statistics used
  4461.       in the profit and loss account. It also updates the balance for
  4462.       the suppliers account.
  4463.  
  4464.       pause off : Escape off
  4465.       for purchases new record
  4466.          copy all from input
  4467.       next
  4468.       for stats
  4469.          if input.type = "Invoice" then
  4470.             stats.creditors = stats.creditors + input.amount
  4471.          end if
  4472.          if input.type = "CreditNote" then
  4473.             stats.creditors = stats.creditors - input.amount
  4474.          end if
  4475.          if input.type = "Payment" then
  4476.             stats.creditors = stats.creditors - input.amount
  4477.             if input.paidby = "cash" then
  4478.                stats.cashbalance = stats.cashbalance - input.amount
  4479.             else
  4480.                stats.bankbalance = stats.bankbalance - input.amount
  4481.             end if
  4482.          end if
  4483.       next
  4484.       for ACbalances with supplier = input supplier
  4485.          if input.type = "Invoice" then
  4486.             ACbalances.balance = ACbalances.balance + input.amount
  4487.          else
  4488.             ACbalances.balance = ACbalances.balance - input.amount
  4489.          end if
  4490.       next
  4491.  
  4492.       Whenever you need to know statistics for "Debtors", "Cash
  4493.       Balance" etc you can produce them instantly with a procedure
  4494.       which simply lists data from the statistics forms.
  4495.  
  4496.       Whenever you use running statistics in this way you should also
  4497.       create a procedure which does calculate them from the raw data.
  4498.       If you ever, for one reason or another, have to edit data
  4499.       directly in "Data entry" then your "running statistics" will no
  4500.       longer be accurate. You can run this procedure to correct them.
  4501.  
  4502.  
  4503.  
  4504.  
  4505.  
  4506.  
  4507.  
  4508.  
  4509.  
  4510.  
  4511.  
  4512.                                 - 77 -
  4513. ................................................................................
  4514.       MULTIPLE COLUMNS                                MULTIPLE COLUMNS
  4515.  
  4516.       You may occasionally need to list data in order but in more
  4517.       than one column. Indexes for technical manuals are a common
  4518.       example. It would be nice if you could send the printer head
  4519.       back to the top of the page for each column but you can't. You
  4520.       must therefore get all the data for each horizontal line into
  4521.       memory at the same time and then print it.
  4522.  
  4523.       The following example prints the "Title" field from a "Films"
  4524.       form in alphabetic order in two columns with fifty lines on
  4525.       each page. To do this a field "No" is added to the form. This
  4526.       is an integer field and it is indexed.
  4527.  
  4528.       declare output fields
  4529.          films.title : righttitle
  4530.       end
  4531.       declare variables
  4532.          x as number  : y as number : lasttitle as text
  4533.       end
  4534.       '................UPDATE THE No FIELD......
  4535.       for films with title in order
  4536.          y = total records
  4537.          x = x + 1
  4538.          display status "Updating No field record" + x + "of" + y
  4539.          films.No = x
  4540.          update record
  4541.       next
  4542.       '.................PRINT IN TWO COLUMNS.................
  4543.       x = 0                        'reuse x as counter
  4544.       do
  4545.          for films with title > lasttitle
  4546.             x = x + 1
  4547.             for films alias col2 with No = films.No + 50
  4548.               righttitle = col2.title
  4549.             next
  4550.             print list items
  4551.             lasttitle = righttitle : righttitle = blank
  4552.             if mod(x,50) = 0 then
  4553.                page feed : Exit for
  4554.             end if
  4555.          next
  4556.          if lasttitle = blank then exit do
  4557.       loop
  4558.  
  4559.       ........................Format..................
  4560.  
  4561.       .list items
  4562.             { Films.title field  }      {  Righttitle Field  }
  4563.       .end
  4564.  
  4565.  
  4566.  
  4567.  
  4568.  
  4569.                                 - 78 -
  4570. ................................................................................
  4571.       Printing System Val.                        Printing System Val.
  4572.  
  4573.       In Easy Base procedures most system values are supplied as
  4574.       fields and can be declared as output fields. Others are
  4575.       internal values and cannot.
  4576.  
  4577.       The internal values are:-
  4578.  
  4579.       System Date
  4580.       System Time
  4581.       Pi
  4582.       Terminal Number
  4583.  
  4584.       To print an internal value you must declare an ad hoc field and
  4585.       transfer the system value to it.
  4586.  
  4587.       Declare output fields
  4588.          date
  4589.       end
  4590.       date = system date
  4591.  
  4592.  
  4593.  
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.  
  4620.  
  4621.  
  4622.  
  4623.  
  4624.  
  4625.  
  4626.                                 - 79 -
  4627. ................................................................................
  4628.       Q AND A INPUT SCREEN                        Q AND A INPUT SCREEN
  4629.  
  4630.       If, for a procedure you have to collect many items of data via
  4631.       an input screen, then presenting all the fields and their
  4632.       labels at once can be confusing to an operator.  You can start
  4633.       with an empty screen other than the first field and its prompt
  4634.       then have each subsequent prompt "Pop up" when the previous
  4635.       field has been filled.
  4636.  
  4637.       To do this you make all your input fields without a background
  4638.       (Text, Alt1 or Alt2) and you create fields for the prompts
  4639.       which have no user entry and also show no background.
  4640.  
  4641.       Ex.
  4642.  
  4643.       To collect data for paymethod, customer, and amount lay out the
  4644.       following fields:-
  4645.  
  4646.               Enter Method of payment....     { Paymethod Field }
  4647.               { Pop1 Field               }    { Customer Field  }
  4648.               { Pop2 Field               }    { Amount Field   }
  4649.  
  4650.       The "Pop1" field is derived:-
  4651.  
  4652.          If(Pop1 = blank and paymethod = blank,blank,"Enter Customers
  4653.                  name.........")
  4654.  
  4655.       and the "Pop2" field is derived:-
  4656.  
  4657.          If(Pop2 = blank and customer = blank,blank,"Enter Amount...
  4658.                 ...............")
  4659.  
  4660.  
  4661.  
  4662.  
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672.  
  4673.  
  4674.  
  4675.  
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.  
  4682.  
  4683.                                 - 80 -
  4684. ................................................................................
  4685.       RUNTIME AUTO START                            RUNTIME AUTO START
  4686.  
  4687.       If you intend to distribute an application using the Easy Base
  4688.       Runtime Module, you can have the module start automatically on
  4689.       a particular user menu by giving that menu the sign on password
  4690.       "Autostart".
  4691.  
  4692.       Each time the runtime module starts it searches for a menu with
  4693.       this password. If it finds one, it skips the sign on screen and
  4694.       starts automatically on this menu.
  4695.  
  4696.       The "Autostart" password has no significance while developing
  4697.       in Easy Base. It is treated as any other sign on password.
  4698.  
  4699.  
  4700.  
  4701.  
  4702.  
  4703.  
  4704.  
  4705.  
  4706.  
  4707.  
  4708.  
  4709.  
  4710.  
  4711.  
  4712.  
  4713.  
  4714.  
  4715.  
  4716.  
  4717.  
  4718.  
  4719.  
  4720.  
  4721.  
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.  
  4728.  
  4729.  
  4730.  
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.                                 - 81 -
  4741. ................................................................................
  4742.       SET SYSTEM VALUES                              SET SYSTEM VALUES
  4743.  
  4744.       The System values System date, System Time and Output can be
  4745.       set within procedure code.
  4746.  
  4747.       Ex.
  4748.          System Date = input.date
  4749.       Ex.
  4750.          If input.print = "Yes" then Output = "Printer"
  4751.  
  4752.       Setting the output from an input screen field means that the
  4753.       user can change the output destination without having to exit
  4754.       back to the menu in procedures which have repeating input
  4755.       screens.
  4756.  
  4757.       If you have several procedures which are individually run to
  4758.       the screen but you also wish to batch execute them to the
  4759.       printer, you can achieve this by including the line:-
  4760.  
  4761.          If Global number = 2 then output = "Printer"
  4762.  
  4763.       then placing the procedures on a batch execute menu which
  4764.       begins with a procedure setting Global Number to 2. and ends
  4765.       with one re setting it to zero.
  4766.  
  4767.  
  4768.  
  4769.  
  4770.  
  4771.  
  4772.  
  4773.  
  4774.  
  4775.  
  4776.  
  4777.  
  4778.  
  4779.  
  4780.  
  4781.  
  4782.  
  4783.  
  4784.  
  4785.  
  4786.  
  4787.  
  4788.  
  4789.  
  4790.  
  4791.  
  4792.  
  4793.  
  4794.  
  4795.  
  4796.  
  4797.                                 - 82 -
  4798. ................................................................................
  4799.       TABULATION                                            TABULATION
  4800.  
  4801.       To create a printout in which fields are enclosed within a
  4802.       lined table use the linedrawing facility in the format editor
  4803.       to create a page header and page footer containing the top and
  4804.       bottom of the table and insert only the vertical lines between
  4805.       the fields in the list items section.
  4806.  
  4807.       Ex.
  4808.  
  4809.       Declare output fields
  4810.          stock.name : stock.price
  4811.       end
  4812.       print page header
  4813.       for stock with name in order
  4814.          if bottom margin < 0.7 then
  4815.             print page footer
  4816.             page feed
  4817.             print page header
  4818.          end if
  4819.          print list items
  4820.       next
  4821.       print page footer
  4822.       Page feed
  4823.  
  4824.       ........................format.........................
  4825.  
  4826.       .page header
  4827.             ╔════════════════════╤═══════════════╗
  4828.             ║ Name               │  Price        ║
  4829.             ╠════════════════════╪═══════════════╣
  4830.       .list items
  4831.             ║ {Name Field     }  │ {Price Fld. } ║
  4832.       .page footer
  4833.             ╚════════════════════╧═══════════════╝
  4834.       .end
  4835.  
  4836.  
  4837.  
  4838.  
  4839.  
  4840.  
  4841.  
  4842.  
  4843.  
  4844.  
  4845.  
  4846.  
  4847.  
  4848.  
  4849.  
  4850.  
  4851.  
  4852.  
  4853.  
  4854.                                 - 83 -
  4855. ................................................................................
  4856.       TOTALS & SUB TOTALS                          TOTALS & SUB TOTALS
  4857.  
  4858.       To produce totals and sub totals in printouts use ad hoc fields
  4859.       to hold the values and increment them during each iteration of
  4860.       the output loops. The following code lists all entries in a
  4861.       clients time sheet form with the cost of work in hand totalled
  4862.       and sub totalled for each client.
  4863.  
  4864.       Declare output fields
  4865.         Clients.Name:Timesheet.Hrs:Timesheet.Mins:Timesheet.Amount
  4866.         Timesheet.date : Subtotal : Grandtotal
  4867.       end
  4868.       Print Report Header
  4869.       for Clients with name in order
  4870.          Print Group Header
  4871.          Subtotal = 0
  4872.          For Timesheet with Acno = Clients.Acno
  4873.             Subtotal = Subtotal + timesheet.amount
  4874.             Grandtotal = Grandtotal + Timesheet.amount
  4875.             Print List Items
  4876.          next
  4877.          Print Group Footer
  4878.       next
  4879.       Print report footer
  4880.  
  4881.       .......................Output Format.........................
  4882.       .Report Header
  4883.          ═════════════════════════════════════════════════════════
  4884.                    Work in Hand Totalled by Client
  4885.          ═════════════════════════════════════════════════════════
  4886.       .Group Header
  4887.  
  4888.          ██████████████████
  4889.       .List Items
  4890.             ████████      ██Hrs ██Mins                     ██████
  4891.       .Group Footer
  4892.                                                        ──────────
  4893.           Total for ██████████████████                 ██████████
  4894.                                                        ══════════
  4895.       .Report Footer
  4896.          ═════════════════════════════════════════════════════════
  4897.          Total Work In Hand                            ██████████
  4898.          ═════════════════════════════════════════════════════════
  4899.       .end
  4900.  
  4901.       The field in the Group Header is Clients.name
  4902.       The fields in List Items are Timesheet.date, Timesheet.Hrs,
  4903.       Timesheet.Mins and Timesheet.amount.
  4904.       The fields in Group Footer are Clients.name and Subtotal.
  4905.       The field in Report Footer is Grandtotal.
  4906.  
  4907.  
  4908.  
  4909.  
  4910.  
  4911.                                 - 84 -
  4912. ................................................................................
  4913.